- Added particle support to g3d viewer

This commit is contained in:
Mark Vejvoda 2010-05-25 18:06:42 +00:00
parent 69d7070f54
commit 4b6e017241
14 changed files with 1043 additions and 286 deletions

View File

@ -101,15 +101,19 @@ if $(WX_AVAILABLE) = "yes" {
if $(WX_AVAILABLE) = "yes" {
SubDir TOP g3d_viewer ;
GLEST_VIEWER_DIRS = . ;
for i in $(GLEST_DIRS) {
GLEST_VIEWER_DIRS =
.
;
for i in $(GLEST_VIEWER_DIRS) {
GLEST_VIEWER_SOURCES += [ Wildcard $(i) : *.cpp *.h ] ;
}
Application glest_g3dviewer : $(GLEST_VIEWER_SOURCES) ;
Application glest_g3dviewer : $(GLEST_VIEWER_SOURCES) ../glest_game/graphics/unit_particle_type.cpp ;
LinkWith glest_g3dviewer : glestlib strefloplib ;
ExternalLibs glest_g3dviewer : SDL GL GLU WX CURL ;
IncludeDir glest_g3dviewer : ../shared_lib/include/$(LIB_INCLUDE_DIRS) $(GLEST_VIEWER_DIRS) ;
ExternalLibs glest_g3dviewer : SDL GL GLU XERCES VORBIS VORBISFILE OGG OPENAL LUA JPEG PNG CURL WX ;
IncludeDir glest_g3dviewer : ../shared_lib/include/$(LIB_INCLUDE_DIRS) $(GLEST_VIEWER_DIRS) ../glest_game/graphics ../glest_game/global ../glest_game/sound ../glest_game/game ;
}
### Configurator ###

View File

@ -7,11 +7,15 @@
#include "graphics_interface.h"
#include "util.h"
#include "conversion.h"
#include "platform_common.h"
#include "xml_parser.h"
using namespace Shared::Platform;
using namespace Shared::PlatformCommon;
using namespace Shared::Graphics;
using namespace Shared::Graphics::Gl;
using namespace Shared::Util;
using namespace Shared::Xml;
using namespace std;
@ -42,7 +46,9 @@ MainWindow::MainWindow(const string &modelPath)
{
//getGlPlatformExtensions();
renderer= Renderer::getInstance();
this->modelPath= modelPath;
if(modelPath != "") {
this->modelPathList.push_back(modelPath);
}
model= NULL;
playerColor= Renderer::pcRed;
@ -60,6 +66,7 @@ MainWindow::MainWindow(const string &modelPath)
//menu
menuFile= new wxMenu();
menuFile->Append(miFileLoad, wxT("Load"));
menuFile->Append(miFileLoadParticleXML, wxT("Load Particle XML"));
menu->Append(menuFile, wxT("File"));
//mode
@ -116,16 +123,7 @@ void MainWindow::init(){
glCanvas->SetCurrent();
renderer->init();
if(!modelPath.empty()){
Model *tmpModel= new ModelGl();
printf("In [%s::%s] modelPath = [%s]\n",__FILE__,__FUNCTION__,modelPath.c_str());
renderer->loadTheModel(tmpModel, modelPath);
model= tmpModel;
GetStatusBar()->SetStatusText(ToUnicode(getModelInfo().c_str()));
}
loadModel("");
//SetTitle(ToUnicode(winHeader + "; " + modelPath));
}
@ -138,6 +136,14 @@ void MainWindow::onPaint(wxPaintEvent &event){
renderer->renderTheModel(model, anim);
//int updateLoops = 100;
int updateLoops = 1;
for(int i=0; i< updateLoops; ++i) {
renderer->updateParticleManager();
}
renderer->renderParticleManager();
glCanvas->SwapBuffers();
}
@ -170,14 +176,98 @@ void MainWindow::onMenuFileLoad(wxCommandEvent &event){
wxFileDialog fileDialog(this);
fileDialog.SetWildcard(wxT("G3D files (*.g3d)|*.g3d"));
if(fileDialog.ShowModal()==wxID_OK){
modelPathList.clear();
loadModel((const char*)wxFNCONV(fileDialog.GetPath().c_str()));
}
}
void MainWindow::onMenuFileLoadParticleXML(wxCommandEvent &event){
string fileName;
wxFileDialog fileDialog(this);
fileDialog.SetWildcard(wxT("XML files (*.xml)|*.xml"));
if(fileDialog.ShowModal()==wxID_OK){
string path = (const char*)wxFNCONV(fileDialog.GetPath().c_str());
loadParticle(path);
}
}
void MainWindow::loadModel(string path) {
if(path != "" && fileExists(path) == true) {
this->modelPathList.push_back(path);
}
for(int idx =0; idx < this->modelPathList.size(); idx++) {
string modelPath = this->modelPathList[idx];
//this->modelPath = path;
delete model;
Model *tmpModel= new ModelGl();
renderer->loadTheModel(tmpModel, (const char*)wxFNCONV(fileDialog.GetPath().c_str()));
renderer->loadTheModel(tmpModel, modelPath);
model= tmpModel;
GetStatusBar()->SetStatusText(ToUnicode(getModelInfo().c_str()));
}
}
void MainWindow::loadParticle(string path) {
if(path != "" && fileExists(path) == true) {
this->particlePathList.push_back(path);
}
if(this->particlePathList.size() > 0) {
for(int idx = 0; idx < this->particlePathList.size(); idx++) {
string particlePath = this->particlePathList[idx];
string dir= extractDirectoryPathFromFile(particlePath);
size_t pos = dir.find_last_of("/");
if(pos == dir.length()-1) {
dir.erase(dir.length() -1);
}
particlePath= extractFileFromDirectoryPath(particlePath);
std::string unitXML = dir + "/" + extractFileFromDirectoryPath(dir) + ".xml";
int size = -1;
int height = -1;
if(fileExists(unitXML) == true) {
XmlTree xmlTree;
xmlTree.load(unitXML);
const XmlNode *unitNode= xmlTree.getRootNode();
const XmlNode *parametersNode= unitNode->getChild("parameters");
//size
size= parametersNode->getChild("size")->getAttribute("value")->getIntValue();
//height
height= parametersNode->getChild("height")->getAttribute("value")->getIntValue();
}
std::cout << "About to load [" << particlePath << "] from [" << dir << "] unit [" << unitXML << "]" << std::endl;
UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType();
unitParticleSystemType->load(dir, dir + "/" + particlePath, renderer->getNewTexture2D());
unitParticleSystemTypes.push_back(unitParticleSystemType);
for(std::vector<UnitParticleSystemType *>::const_iterator it= unitParticleSystemTypes.begin(); it != unitParticleSystemTypes.end(); ++it) {
UnitParticleSystem *ups= new UnitParticleSystem(200);
(*it)->setValues(ups);
if(size > 0) {
//getCurrVectorFlat() + Vec3f(0.f, type->getHeight()/2.f, 0.f);
Vec3f vec = Vec3f(0.f, height / 2.f, 0.f);
ups->setPos(vec);
}
//ups->setFactionColor(getFaction()->getTexture()->getPixmap()->getPixel3f(0,0));
ups->setFactionColor(renderer->getPlayerColorTexture(playerColor)->getPixmap()->getPixel3f(0,0));
unitParticleSystems.push_back(ups);
renderer->manageParticleSystem(ups);
ups->setVisible(true);
}
renderer->initTextureManager();
}
}
}
void MainWindow::onMenuModeNormals(wxCommandEvent &event){
renderer->toggleNormals();
menuMode->Check(miModeNormals, renderer->getNormals());
@ -256,10 +346,124 @@ string MainWindow::getModelInfo(){
return str;
}
void MainWindow::onKeyDown(wxKeyEvent &e) {
/*
if (currentBrush == btHeight || currentBrush == btGradient) { // 'height' brush
if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') {
height = e.GetKeyCode() - 48; // '0'-'5' == 0-5
if (e.GetModifiers() == wxMOD_CONTROL) { // Ctrl means negative
height = -height ;
}
int id_offset = heightCount / 2 + height + 1;
if (currentBrush == btHeight) {
wxCommandEvent evt(wxEVT_NULL, miBrushHeight + id_offset);
onMenuBrushHeight(evt);
} else {
wxCommandEvent evt(wxEVT_NULL, miBrushGradient + id_offset);
onMenuBrushGradient(evt);
}
return;
}
}
if (currentBrush == btSurface) { // surface texture
if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '5') {
surface = e.GetKeyCode() - 48; // '1'-'5' == 1-5
wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface);
onMenuBrushSurface(evt);
return;
}
}
if (currentBrush == btObject) {
bool valid = true;
if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '9') {
object = e.GetKeyCode() - 48; // '1'-'9' == 1-9
} else if (e.GetKeyCode() == '0') { // '0' == 10
object = 10;
} else if (e.GetKeyCode() == '-') { // '-' == 0
object = 0;
} else {
valid = false;
}
if (valid) {
wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1);
onMenuBrushObject(evt);
return;
}
}
if (currentBrush == btResource) {
if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') {
resource = e.GetKeyCode() - 48; // '0'-'5' == 0-5
wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1);
onMenuBrushResource(evt);
return;
}
}
if (currentBrush == btStartLocation) {
if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '8') {
startLocation = e.GetKeyCode() - 48; // '1'-'8' == 0-7
wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation);
onMenuBrushStartLocation(evt);
return;
}
}
if (e.GetKeyCode() == 'H') {
wxCommandEvent evt(wxEVT_NULL, miBrushHeight + height + heightCount / 2 + 1);
onMenuBrushHeight(evt);
} else if (e.GetKeyCode() == ' ') {
if (resourceUnderMouse != 0) {
wxCommandEvent evt(wxEVT_NULL, miBrushResource + resourceUnderMouse + 1);
onMenuBrushResource(evt);
} else {
wxCommandEvent evt(wxEVT_NULL, miBrushObject + objectUnderMouse + 1);
onMenuBrushObject(evt);
}
} else if (e.GetKeyCode() == 'G') {
wxCommandEvent evt(wxEVT_NULL, miBrushGradient + height + heightCount / 2 + 1);
onMenuBrushGradient(evt);
} else if (e.GetKeyCode() == 'S') {
wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface);
onMenuBrushSurface(evt);
} else if (e.GetKeyCode() == 'O') {
wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1);
onMenuBrushObject(evt);
} else if (e.GetKeyCode() == 'R') {
wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1);
onMenuBrushResource(evt);
} else if (e.GetKeyCode() == 'L') {
wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation + 1);
onMenuBrushStartLocation(evt);
} else {
e.Skip();
}
*/
if (e.GetKeyCode() == 'R') {
renderer->end();
for(int idx = 0; idx < unitParticleSystems.size(); ++idx) {
//UnitParticleSystem *ups = unitParticleSystems[idx];
//delete ups;
//ups = NULL;
}
unitParticleSystems.clear();
for(int idx = 0; idx < unitParticleSystemTypes.size(); ++idx) {
//UnitParticleSystemType *unitParticleSystemType = unitParticleSystemTypes[idx];
//delete unitParticleSystemType;
//unitParticleSystemType = NULL;
}
unitParticleSystemTypes.clear();
loadModel("");
loadParticle("");
}
}
BEGIN_EVENT_TABLE(MainWindow, wxFrame)
EVT_TIMER(-1, MainWindow::onTimer)
EVT_CLOSE(MainWindow::onClose)
EVT_MENU(miFileLoad, MainWindow::onMenuFileLoad)
EVT_MENU(miFileLoadParticleXML, MainWindow::onMenuFileLoadParticleXML)
EVT_MENU(miModeWireframe, MainWindow::onMenuModeWireframe)
EVT_MENU(miModeNormals, MainWindow::onMenuModeNormals)
@ -278,6 +482,15 @@ END_EVENT_TABLE()
// class GlCanvas
// =====================================================
void translateCoords(wxWindow *wnd, int &x, int &y) {
#ifdef WIN32
int cx, cy;
wnd->GetPosition(&cx, &cy);
x += cx;
y += cy;
#endif
}
GlCanvas::GlCanvas(MainWindow * mainWindow):
wxGLCanvas(mainWindow, -1, wxDefaultPosition)
{
@ -288,8 +501,16 @@ void GlCanvas::onMouseMove(wxMouseEvent &event){
mainWindow->onMouseMove(event);
}
void GlCanvas::onKeyDown(wxKeyEvent &event) {
int x, y;
event.GetPosition(&x, &y);
translateCoords(this, x, y);
mainWindow->onKeyDown(event);
}
BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas)
EVT_MOTION(GlCanvas::onMouseMove)
EVT_KEY_DOWN(GlCanvas::onKeyDown)
END_EVENT_TABLE()
// ===============================================

View File

@ -8,8 +8,11 @@
#include "renderer.h"
#include "util.h"
#include "particle_type.h"
#include "unit_particle_type.h"
using std::string;
using namespace Glest::Game;
namespace Shared{ namespace G3dViewer{
@ -29,6 +32,7 @@ public:
enum MenuId{
miFileLoad,
miFileLoadParticleXML,
miModeWireframe,
miModeNormals,
miModeGrid,
@ -53,7 +57,11 @@ private:
wxMenu *menuCustomColor;
Model *model;
string modelPath;
//string modelPath;
//string ParticlePath;
std::vector<string> modelPathList;
std::vector<string> particlePathList;
float speed;
float anim;
@ -61,6 +69,12 @@ private:
int lastX, lastY;
Renderer::PlayerColor playerColor;
std::vector<UnitParticleSystemType *> unitParticleSystemTypes;
std::vector<UnitParticleSystem *> unitParticleSystems;
void loadModel(string path);
void loadParticle(string path);
public:
MainWindow(const string &modelPath);
~MainWindow();
@ -71,6 +85,7 @@ public:
void onPaint(wxPaintEvent &event);
void onClose(wxCloseEvent &event);
void onMenuFileLoad(wxCommandEvent &event);
void onMenuFileLoadParticleXML(wxCommandEvent &event);
void onMenuModeNormals(wxCommandEvent &event);
void onMenuModeWireframe(wxCommandEvent &event);
void onMenuModeGrid(wxCommandEvent &event);
@ -83,6 +98,8 @@ public:
void onMouseMove(wxMouseEvent &event);
void onTimer(wxTimerEvent &event);
void onKeyDown(wxKeyEvent &e);
string getModelInfo();
};
@ -98,7 +115,8 @@ public:
GlCanvas(MainWindow *mainWindow);
void onMouseMove(wxMouseEvent &event);
void onPaint(wxPaintEvent &event);
void onPaint(wxPaintEvent &event);
void onKeyDown(wxKeyEvent &event);
private:
MainWindow *mainWindow;

View File

@ -77,11 +77,17 @@ Renderer::Renderer(){
grid= true;
modelRenderer = NULL;
textureManager = NULL;
particleRenderer = NULL;
particleManager = NULL;
}
Renderer::~Renderer(){
delete modelRenderer;
delete textureManager;
delete particleRenderer;
//resources
delete particleManager;
}
Renderer * Renderer::getInstance(){
@ -130,6 +136,11 @@ void Renderer::checkExtension(const string &extension, const string &msg){
}
}
Texture2D * Renderer::getNewTexture2D() {
Texture2D *newTexture = textureManager->newTexture2D();
return newTexture;
}
void Renderer::init(){
assertGl();
@ -141,6 +152,10 @@ void Renderer::init(){
modelRenderer= gf->newModelRenderer();
textureManager= gf->newTextureManager();
particleRenderer= gf->newParticleRenderer();
//resources
particleManager= gf->newParticleManager();
//red tex
customTextureRed= textureManager->newTexture2D();
@ -299,4 +314,51 @@ void Renderer::renderTheModel(Model *model, float f){
}
}
void Renderer::manageParticleSystem(ParticleSystem *particleSystem){
particleManager->manage(particleSystem);
}
void Renderer::updateParticleManager(){
particleManager->update();
}
void Renderer::renderParticleManager(){
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDepthFunc(GL_LESS);
particleRenderer->renderManager(particleManager, modelRenderer);
glPopAttrib();
}
Texture2D * Renderer::getPlayerColorTexture(PlayerColor playerColor) {
Texture2D *customTexture;
switch(playerColor){
case pcRed:
customTexture= customTextureRed;
break;
case pcBlue:
customTexture= customTextureBlue;
break;
case pcYellow:
customTexture= customTextureYellow;
break;
case pcGreen:
customTexture= customTextureGreen;
break;
default:
assert(false);
}
return customTexture;
}
void Renderer::initTextureManager() {
textureManager->init();
}
void Renderer::end() {
//delete resources
//textureManager->end();
particleManager->end();
}
}}//end namespace

View File

@ -11,7 +11,10 @@
#include "model_renderer.h"
#include "texture_manager.h"
#include "model.h"
#include "texture.h"
#include "texture.h"
#include "particle_renderer.h"
//#include "model_manager.h"
//#include "graphics_factory_gl.h"
@ -19,7 +22,9 @@ using Shared::Graphics::ModelRenderer;
using Shared::Graphics::TextureManager;
using Shared::Graphics::Model;
using Shared::Graphics::Texture2D;
using Shared::Graphics::ParticleRenderer;
using Shared::Graphics::ParticleManager;
using Shared::Graphics::ParticleSystem;
//#include "model_renderer.h"
using Shared::Graphics::MeshCallback;
@ -67,6 +72,10 @@ private:
ModelRenderer *modelRenderer;
TextureManager *textureManager;
ParticleRenderer *particleRenderer;
ParticleManager *particleManager;
Texture2D *customTextureRed;
Texture2D *customTextureBlue;
Texture2D *customTextureYellow;
@ -96,6 +105,14 @@ public:
void loadTheModel(Model *model, string file);
void renderTheModel(Model *model, float f);
void manageParticleSystem(ParticleSystem *particleSystem);
void updateParticleManager();
void renderParticleManager();
Texture2D *getPlayerColorTexture(PlayerColor playerColor);
Texture2D * getNewTexture2D();
void initTextureManager();
void end();
};
}}//end namespace

View File

@ -26,7 +26,7 @@ using namespace Shared::Platform;
namespace Glest{ namespace Game{
const string mailString= "contact_game@glest.org";
const string glestVersionString= "v3.3.5-alpha2";
const string glestVersionString= "v3.3.5-alpha3";
string getCrashDumpFileName(){
return "glest" + glestVersionString + ".dmp";

View File

@ -14,7 +14,6 @@
#include "util.h"
#include "core_data.h"
#include "xml_parser.h"
#include "renderer.h"
#include "config.h"
#include "game_constants.h"
@ -30,17 +29,15 @@ namespace Glest{ namespace Game{
// =====================================================
UnitParticleSystemType::UnitParticleSystemType(){
texture = NULL;
}
void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir){
Renderer &renderer= Renderer::getInstance();
void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir, Texture2D *newTexture){
//texture
const XmlNode *textureNode= particleSystemNode->getChild("texture");
bool textureEnabled= textureNode->getAttribute("value")->getBoolValue();
if(textureEnabled){
texture= renderer.newTexture2D(rsGame);
if(textureEnabled == true) {
texture = newTexture;
if(textureNode->getAttribute("luminance")->getBoolValue()){
texture->setFormat(Texture::fAlpha);
texture->getPixmap()->init(1);
@ -52,6 +49,9 @@ void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const strin
}
else{
texture= NULL;
delete newTexture;
newTexture = NULL;
}
//primitive
@ -186,14 +186,14 @@ void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
ups->setBlendMode(ParticleSystem::strToBlendMode(mode));
}
void UnitParticleSystemType::load(const string &dir, const string &path){
void UnitParticleSystemType::load(const string &dir, const string &path, Texture2D *newTexture){
try{
XmlTree xmlTree;
xmlTree.load(path);
const XmlNode *particleSystemNode= xmlTree.getRootNode();
UnitParticleSystemType::load(particleSystemNode, dir);
UnitParticleSystemType::load(particleSystemNode, dir, newTexture);
}
catch(const exception &e){
throw runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what());

View File

@ -64,8 +64,8 @@ protected:
public:
UnitParticleSystemType();
void load(const XmlNode *particleSystemNode, const string &dir);
void load(const string &dir, const string &path);
void load(const XmlNode *particleSystemNode, const string &dir, Texture2D *newTexture);
void load(const string &dir, const string &path, Texture2D *newTexture);
void setValues(UnitParticleSystem *uts);
};

View File

@ -65,290 +65,305 @@ void ConnectionSlot::update() {
}
void ConnectionSlot::update(bool checkForNewClients) {
if(socket == NULL) {
if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false;
if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false;
if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false;
//if(networkGameDataSynchCheckOkFogOfWar) networkGameDataSynchCheckOkFogOfWar = false;
clearThreadErrorList();
// Is the listener socket ready to be read?
//if(serverInterface->getServerSocket()->isReadable() == true)
if(checkForNewClients == true) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount());
bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0);
if(serverInterface->getServerSocket()->hasDataToRead() == true) {
socket = serverInterface->getServerSocket()->accept();
serverInterface->updateListen();
}
//send intro message when connected
if(socket != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] accepted new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount());
connectedTime = time(NULL);
try {
if(socket == NULL) {
if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false;
if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false;
if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false;
// Is the listener socket ready to be read?
//if(serverInterface->getServerSocket()->isReadable() == true)
if(checkForNewClients == true) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount());
bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0);
if(serverInterface->getServerSocket()->hasDataToRead() == true) {
socket = serverInterface->getServerSocket()->accept();
serverInterface->updateListen();
}
//send intro message when connected
if(socket != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] accepted new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,serverInterface->getOpenSlotCount());
connectedTime = time(NULL);
chatText.clear();
chatSender.clear();
chatTeamIndex= -1;
if(hasOpenSlots == false) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] no open slots, disconnecting client\n",__FILE__,__FUNCTION__);
NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), socket->getHostName(), playerIndex, nmgstNoSlots);
sendMessage(&networkMessageIntro);
close();
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__);
NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), socket->getHostName(), playerIndex, nmgstOk);
sendMessage(&networkMessageIntro);
}
}
}
}
else {
if(socket->isConnected()) {
chatText.clear();
chatSender.clear();
chatTeamIndex= -1;
if(hasOpenSlots == false) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] no open slots, disconnecting client\n",__FILE__,__FUNCTION__);
NetworkMessageType networkMessageType= getNextMessageType();
NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), socket->getHostName(), playerIndex, nmgstNoSlots);
sendMessage(&networkMessageIntro);
//process incoming commands
switch(networkMessageType) {
close();
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__);
case nmtInvalid:
break;
NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), socket->getHostName(), playerIndex, nmgstOk);
sendMessage(&networkMessageIntro);
}
}
}
}
else {
if(socket->isConnected()) {
chatText.clear();
chatSender.clear();
chatTeamIndex= -1;
case nmtText:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__);
NetworkMessageType networkMessageType= getNextMessageType();
NetworkMessageText networkMessageText;
if(receiveMessage(&networkMessageText)) {
chatText = networkMessageText.getText();
chatSender = networkMessageText.getSender();
chatTeamIndex = networkMessageText.getTeamIndex();
//process incoming commands
switch(networkMessageType) {
case nmtInvalid:
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] chatText [%s] chatSender [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,chatText.c_str(),chatSender.c_str(),chatTeamIndex);
}
}
break;
case nmtText:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__);
//command list
case nmtCommandList: {
NetworkMessageText networkMessageText;
if(receiveMessage(&networkMessageText)) {
chatText = networkMessageText.getText();
chatSender = networkMessageText.getSender();
chatTeamIndex = networkMessageText.getTeamIndex();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtCommandList\n",__FILE__,__FUNCTION__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] chatText [%s] chatSender [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,chatText.c_str(),chatSender.c_str(),chatTeamIndex);
}
}
break;
//throw runtime_error("test");
//command list
case nmtCommandList: {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtCommandList\n",__FILE__,__FUNCTION__);
NetworkMessageCommandList networkMessageCommandList;
if(receiveMessage(&networkMessageCommandList)) {
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i) {
serverInterface->requestCommand(networkMessageCommandList.getCommand(i));
NetworkMessageCommandList networkMessageCommandList;
if(receiveMessage(&networkMessageCommandList)) {
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i) {
serverInterface->requestCommand(networkMessageCommandList.getCommand(i));
}
}
}
}
break;
break;
//process intro messages
case nmtIntro:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtIntro\n",__FILE__,__FUNCTION__);
NetworkMessageIntro networkMessageIntro;
if(receiveMessage(&networkMessageIntro))
//process intro messages
case nmtIntro:
{
gotIntro = true;
name= networkMessageIntro.getName();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtIntro\n",__FILE__,__FUNCTION__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s]\n",__FILE__,__FUNCTION__,name.c_str());
NetworkMessageIntro networkMessageIntro;
if(receiveMessage(&networkMessageIntro))
{
gotIntro = true;
name= networkMessageIntro.getName();
if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s]\n",__FILE__,__FUNCTION__,name.c_str());
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings());
sendMessage(&networkMessageSynchNetworkGameData);
}
}
}
break;
if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__);
//process datasynch messages
case nmtSynchNetworkGameDataStatus:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__);
NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus;
if(receiveMessage(&networkMessageSynchNetworkGameDataStatus))
{
receivedNetworkGameStatus = true;
Config &config = Config::getInstance();
string scenarioDir = "";
if(serverInterface->getGameSettings()->getScenarioDir() != "") {
scenarioDir = serverInterface->getGameSettings()->getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str());
}
//tileset
int32 tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), ".xml", NULL);
int32 techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL);
Checksum checksum;
string file = Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir);
checksum.addFile(file);
int32 mapCRC = checksum.getSum();
networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC);
networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC);
networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC);
// For testing
//techCRC++;
if( networkGameDataSynchCheckOkMap == true &&
networkGameDataSynchCheckOkTile == true &&
networkGameDataSynchCheckOkTech == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__);
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC());
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC());
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC());
if(allowDownloadDataSynch == true) {
// Now get all filenames with their CRC values and send to the client
vctFileList.clear();
Config &config = Config::getInstance();
string scenarioDir = "";
if(serverInterface->getGameSettings()->getScenarioDir() != "") {
scenarioDir = serverInterface->getGameSettings()->getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str());
}
if(networkGameDataSynchCheckOkTile == false) {
if(tilesetCRC == 0) {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", "", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList);
}
else {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
}
}
if(networkGameDataSynchCheckOkTech == false) {
if(techCRC == 0) {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
}
else {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
}
}
if(networkGameDataSynchCheckOkMap == false) {
vctFileList.push_back(std::pair<string,int32>(Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir),mapCRC));
}
//for(int i = 0; i < vctFileList.size(); i++)
//{
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), 1, vctFileList[0].second, vctFileList[0].first);
sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck);
//}
}
}
}
}
break;
case nmtSynchNetworkGameDataFileCRCCheck:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck\n",__FILE__,__FUNCTION__);
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck;
if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck))
{
int fileIndex = networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex();
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), fileIndex, vctFileList[fileIndex-1].second, vctFileList[fileIndex-1].first);
sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck);
}
}
break;
case nmtSynchNetworkGameDataFileGet:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileGet\n",__FILE__,__FUNCTION__);
NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet;
if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) {
FileTransferInfo fileInfo;
fileInfo.hostType = eServer;
//fileInfo.serverIP = this->ip.getString();
fileInfo.serverPort = Config::getInstance().getInt("ServerPort",intToStr(GameConstants::serverPort).c_str());
fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName();
FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo);
fileXferThread->start();
}
}
break;
case nmtSwitchSetupRequest:
{
SwitchSetupRequest switchSetupRequest;
if(receiveMessage(&switchSetupRequest)) {
if(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]==NULL) {
serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]= new SwitchSetupRequest();
}
*(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()])=switchSetupRequest;
}
break;
}
case nmtReady:
{
// its simply ignored here. Probably we are starting a game
break;
}
default:
{
if(gotIntro == true) {
//throw runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType));
string sErr = "Unexpected message in connection slot: " + intToStr(networkMessageType);
//sendTextMessage(sErr,-1);
DisplayErrorMessage(sErr);
return;
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings());
sendMessage(&networkMessageSynchNetworkGameData);
}
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got invalid message type before intro, disconnecting socket.\n",__FILE__,__FUNCTION__,__LINE__);
close();
}
break;
//process datasynch messages
case nmtSynchNetworkGameDataStatus:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__);
NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus;
if(receiveMessage(&networkMessageSynchNetworkGameDataStatus))
{
receivedNetworkGameStatus = true;
Config &config = Config::getInstance();
string scenarioDir = "";
if(serverInterface->getGameSettings()->getScenarioDir() != "") {
scenarioDir = serverInterface->getGameSettings()->getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str());
}
//tileset
int32 tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), ".xml", NULL);
int32 techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL);
Checksum checksum;
string file = Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir);
checksum.addFile(file);
int32 mapCRC = checksum.getSum();
networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC);
networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC);
networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC);
// For testing
//techCRC++;
if( networkGameDataSynchCheckOkMap == true &&
networkGameDataSynchCheckOkTile == true &&
networkGameDataSynchCheckOkTech == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__);
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC());
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC());
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC());
if(allowDownloadDataSynch == true) {
// Now get all filenames with their CRC values and send to the client
vctFileList.clear();
Config &config = Config::getInstance();
string scenarioDir = "";
if(serverInterface->getGameSettings()->getScenarioDir() != "") {
scenarioDir = serverInterface->getGameSettings()->getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str());
}
if(networkGameDataSynchCheckOkTile == false) {
if(tilesetCRC == 0) {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", "", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList);
}
else {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_tilesets) + "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
}
}
if(networkGameDataSynchCheckOkTech == false) {
if(techCRC == 0) {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
}
else {
//vctFileList = getFolderTreeContentsCheckSumListRecursively(string(GameConstants::folder_path_techs) + "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
}
}
if(networkGameDataSynchCheckOkMap == false) {
vctFileList.push_back(std::pair<string,int32>(Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir),mapCRC));
}
//for(int i = 0; i < vctFileList.size(); i++)
//{
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), 1, vctFileList[0].second, vctFileList[0].first);
sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck);
//}
}
}
}
}
}
break;
case nmtSynchNetworkGameDataFileCRCCheck:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck\n",__FILE__,__FUNCTION__);
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck;
if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck))
{
int fileIndex = networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex();
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), fileIndex, vctFileList[fileIndex-1].second, vctFileList[fileIndex-1].first);
sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck);
}
}
break;
case nmtSynchNetworkGameDataFileGet:
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileGet\n",__FILE__,__FUNCTION__);
NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet;
if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) {
FileTransferInfo fileInfo;
fileInfo.hostType = eServer;
//fileInfo.serverIP = this->ip.getString();
fileInfo.serverPort = Config::getInstance().getInt("ServerPort",intToStr(GameConstants::serverPort).c_str());
fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName();
FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo);
fileXferThread->start();
}
}
break;
case nmtSwitchSetupRequest:
{
SwitchSetupRequest switchSetupRequest;
if(receiveMessage(&switchSetupRequest)) {
Mutex *mutex = getServerSynchAccessor();
if(mutex != NULL) mutex->p();
if(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]==NULL) {
serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()]= new SwitchSetupRequest();
}
*(serverInterface->getSwitchSetupRequests()[switchSetupRequest.getCurrentFactionIndex()])=switchSetupRequest;
if(mutex != NULL) mutex->v();
}
break;
}
case nmtReady:
{
// its simply ignored here. Probably we are starting a game
break;
}
default:
{
if(gotIntro == true) {
//throw runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType));
string sErr = "Unexpected message in connection slot: " + intToStr(networkMessageType);
//sendTextMessage(sErr,-1);
//DisplayErrorMessage(sErr);
threadErrorList.push_back(sErr);
return;
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got invalid message type before intro, disconnecting socket.\n",__FILE__,__FUNCTION__,__LINE__);
close();
}
}
}
if(gotIntro == false && difftime(time(NULL),connectedTime) > GameConstants::maxClientConnectHandshakeSecs) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] difftime(time(NULL),connectedTime) = %d\n",__FILE__,__FUNCTION__,__LINE__,difftime(time(NULL),connectedTime));
close();
}
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling close...\n",__FILE__,__FUNCTION__);
if(gotIntro == false && difftime(time(NULL),connectedTime) > GameConstants::maxClientConnectHandshakeSecs) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] difftime(time(NULL),connectedTime) = %d\n",__FILE__,__FUNCTION__,__LINE__,difftime(time(NULL),connectedTime));
close();
}
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling close...\n",__FILE__,__FUNCTION__);
}
catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
close();
}
threadErrorList.push_back(ex.what());
}
}

View File

@ -65,10 +65,13 @@ public:
bool hasValidSocketId();
virtual bool getConnectHasHandshaked() const { return gotIntro; }
std::vector<std::string> getThreadErrorList() const { return threadErrorList; }
void clearThreadErrorList() { threadErrorList.clear(); }
protected:
Mutex * getServerSynchAccessor();
std::vector<std::string> threadErrorList;
};
}}//end namespace

View File

@ -414,6 +414,18 @@ void ServerInterface::update() {
// Examine all threads for completion of delegation
for(int i= 0; i< GameConstants::maxPlayers; ++i) {
if(slotThreads[i] != NULL && slotsCompleted.find(i) == slotsCompleted.end()) {
ConnectionSlot* connectionSlot= slots[i];
if(connectionSlot != NULL) {
std::vector<std::string> errorList = connectionSlot->getThreadErrorList();
if(errorList.size() > 0) {
for(int iErrIdx = 0; iErrIdx < errorList.size(); ++iErrIdx) {
string &sErr = errorList[iErrIdx];
DisplayErrorMessage(sErr);
}
connectionSlot->clearThreadErrorList();
}
}
if(slotThreads[i]->isSignalCompleted() == false &&
slotThreads[i]->getQuitStatus() == false &&
slotThreads[i]->getRunningStatus() == true) {

View File

@ -23,6 +23,7 @@
#include "skill_type.h"
#include "core_data.h"
#include "renderer.h"
#include "game.h"
#ifndef WIN32

View File

@ -0,0 +1,403 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "skill_type.h"
#include <cassert>
#include "sound.h"
#include "util.h"
#include "lang.h"
#include "renderer.h"
#include "particle_type.h"
#include "unit_particle_type.h"
#include "tech_tree.h"
#include "faction_type.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using namespace Shared::Graphics;
namespace Glest{ namespace Game{
// =====================================================
// class SkillType
// =====================================================
SkillType::~SkillType(){
deleteValues(sounds.getSounds().begin(), sounds.getSounds().end());
//remove unitParticleSystemTypes
while(!unitParticleSystemTypes.empty()){
delete unitParticleSystemTypes.back();
unitParticleSystemTypes.pop_back();
}
}
void SkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt, const FactionType *ft){
//name
name= sn->getChild("name")->getAttribute("value")->getRestrictedValue();
//ep cost
mpCost= sn->getChild("ep-cost")->getAttribute("value")->getIntValue();
//speed
speed= sn->getChild("speed")->getAttribute("value")->getIntValue();
//anim speed
animSpeed= sn->getChild("anim-speed")->getAttribute("value")->getIntValue();
//model
string path= sn->getChild("animation")->getAttribute("path")->getRestrictedValue();
animation= Renderer::getInstance().newModel(rsGame);
animation->load(dir + "/" + path);
//particles
if(sn->hasChild("particles")){
const XmlNode *particleNode= sn->getChild("particles");
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
if(particleEnabled){
for(int i=0; i<particleNode->getChildCount(); ++i){
const XmlNode *particleFileNode= particleNode->getChild("particle-file", i);
string path= particleFileNode->getAttribute("path")->getRestrictedValue();
UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType();
unitParticleSystemType->load(dir, dir + "/" + path, Renderer::getInstance().newTexture2D(rsGame));
unitParticleSystemTypes.push_back(unitParticleSystemType);
}
}
}
//sound
const XmlNode *soundNode= sn->getChild("sound");
if(soundNode->getAttribute("enabled")->getBoolValue()){
soundStartTime= soundNode->getAttribute("start-time")->getFloatValue();
sounds.resize(soundNode->getChildCount());
for(int i=0; i<soundNode->getChildCount(); ++i){
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
string path= soundFileNode->getAttribute("path")->getRestrictedValue();
StaticSound *sound= new StaticSound();
sound->load(dir + "/" + path);
sounds[i]= sound;
}
}
}
string SkillType::skillClassToStr(SkillClass skillClass){
switch(skillClass){
case scStop: return "Stop";
case scMove: return "Move";
case scAttack: return "Attack";
case scHarvest: return "Harvest";
case scRepair: return "Repair";
case scBuild: return "Build";
case scDie: return "Die";
case scBeBuilt: return "Be Built";
case scProduce: return "Produce";
case scUpgrade: return "Upgrade";
default:
assert(false);
return "";
};
}
string SkillType::fieldToStr(Field field){
switch(field){
case fLand: return "Land";
case fAir: return "Air";
default:
assert(false);
return "";
};
}
// =====================================================
// class StopSkillType
// =====================================================
StopSkillType::StopSkillType(){
skillClass= scStop;
}
string StopSkillType::toString() const{
return Lang::getInstance().get("Stop");
}
// =====================================================
// class MoveSkillType
// =====================================================
MoveSkillType::MoveSkillType(){
skillClass= scMove;
}
string MoveSkillType::toString() const{
return Lang::getInstance().get("Move");
}
int MoveSkillType::getTotalSpeed(const TotalUpgrade *totalUpgrade) const{
return speed + totalUpgrade->getMoveSpeed();
}
// =====================================================
// class AttackSkillType
// =====================================================
//varios
AttackSkillType::AttackSkillType(){
skillClass= scAttack;
attackType= NULL;
projectile= false;
splash= false;
splashRadius= 0;
projectileParticleSystemType= NULL;
splashParticleSystemType= NULL;
for(int i=0; i<fieldCount; ++i){
attackFields[i]= false;
}
}
AttackSkillType::~AttackSkillType(){
delete projectileParticleSystemType;
delete splashParticleSystemType;
deleteValues(projSounds.getSounds().begin(), projSounds.getSounds().end());
}
void AttackSkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt, const FactionType *ft){
SkillType::load(sn, dir, tt, ft);
//misc
attackStrength= sn->getChild("attack-strenght")->getAttribute("value")->getIntValue();
attackVar= sn->getChild("attack-var")->getAttribute("value")->getIntValue();
attackRange= sn->getChild("attack-range")->getAttribute("value")->getIntValue();
string attackTypeName= sn->getChild("attack-type")->getAttribute("value")->getRestrictedValue();
attackType= tt->getAttackType(attackTypeName);
attackStartTime= sn->getChild("attack-start-time")->getAttribute("value")->getFloatValue();
//attack fields
const XmlNode *attackFieldsNode= sn->getChild("attack-fields");
for(int i=0; i<attackFieldsNode->getChildCount(); ++i){
const XmlNode *fieldNode= attackFieldsNode->getChild("field", i);
string fieldName= fieldNode->getAttribute("value")->getRestrictedValue();
if(fieldName=="land"){
attackFields[fLand]= true;
}
else if(fieldName=="air"){
attackFields[fAir]= true;
}
else{
throw runtime_error("Not a valid field: "+fieldName+": "+ dir);
}
}
//projectile
const XmlNode *projectileNode= sn->getChild("projectile");
projectile= projectileNode->getAttribute("value")->getBoolValue();
if(projectile){
//proj particle
const XmlNode *particleNode= projectileNode->getChild("particle");
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
if(particleEnabled){
string path= particleNode->getAttribute("path")->getRestrictedValue();
projectileParticleSystemType= new ParticleSystemTypeProjectile();
projectileParticleSystemType->load(dir, dir + "/" + path);
}
//proj sounds
const XmlNode *soundNode= projectileNode->getChild("sound");
if(soundNode->getAttribute("enabled")->getBoolValue()){
projSounds.resize(soundNode->getChildCount());
for(int i=0; i<soundNode->getChildCount(); ++i){
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
string path= soundFileNode->getAttribute("path")->getRestrictedValue();
StaticSound *sound= new StaticSound();
sound->load(dir + "/" + path);
projSounds[i]= sound;
}
}
}
//splash
const XmlNode *splashNode= sn->getChild("splash");
splash= splashNode->getAttribute("value")->getBoolValue();
if(splash){
splashRadius= splashNode->getChild("radius")->getAttribute("value")->getIntValue();
splashDamageAll= splashNode->getChild("damage-all")->getAttribute("value")->getBoolValue();
//splash particle
const XmlNode *particleNode= splashNode->getChild("particle");
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
if(particleEnabled){
string path= particleNode->getAttribute("path")->getRestrictedValue();
splashParticleSystemType= new ParticleSystemTypeSplash();
splashParticleSystemType->load(dir, dir + "/" + path);
}
}
}
string AttackSkillType::toString() const{
return Lang::getInstance().get("Attack");
}
//get totals
int AttackSkillType::getTotalAttackStrength(const TotalUpgrade *totalUpgrade) const{
return attackStrength + totalUpgrade->getAttackStrength();
}
int AttackSkillType::getTotalAttackRange(const TotalUpgrade *totalUpgrade) const{
return attackRange + totalUpgrade->getAttackRange();
}
// =====================================================
// class BuildSkillType
// =====================================================
BuildSkillType::BuildSkillType(){
skillClass= scBuild;
}
string BuildSkillType::toString() const{
return Lang::getInstance().get("Build");
}
// =====================================================
// class HarvestSkillType
// =====================================================
HarvestSkillType::HarvestSkillType(){
skillClass= scHarvest;
}
string HarvestSkillType::toString() const{
return Lang::getInstance().get("Harvest");
}
// =====================================================
// class RepairSkillType
// =====================================================
RepairSkillType::RepairSkillType(){
skillClass= scRepair;
}
string RepairSkillType::toString() const{
return Lang::getInstance().get("Repair");
}
// =====================================================
// class ProduceSkillType
// =====================================================
ProduceSkillType::ProduceSkillType(){
skillClass= scProduce;
}
string ProduceSkillType::toString() const{
return Lang::getInstance().get("Produce");
}
int ProduceSkillType::getTotalSpeed(const TotalUpgrade *totalUpgrade) const{
return speed + totalUpgrade->getProdSpeed();
}
// =====================================================
// class UpgradeSkillType
// =====================================================
UpgradeSkillType::UpgradeSkillType(){
skillClass= scUpgrade;
}
string UpgradeSkillType::toString() const{
return Lang::getInstance().get("Upgrade");
}
int UpgradeSkillType::getTotalSpeed(const TotalUpgrade *totalUpgrade) const{
return speed + totalUpgrade->getProdSpeed();
}
// =====================================================
// class BeBuiltSkillType
// =====================================================
BeBuiltSkillType::BeBuiltSkillType(){
skillClass= scBeBuilt;
}
string BeBuiltSkillType::toString() const{
return "Be built";
}
// =====================================================
// class MorphSkillType
// =====================================================
MorphSkillType::MorphSkillType(){
skillClass= scMorph;
}
string MorphSkillType::toString() const{
return "Morph";
}
int MorphSkillType::getTotalSpeed(const TotalUpgrade *totalUpgrade) const{
return speed + totalUpgrade->getProdSpeed();
}
// =====================================================
// class DieSkillType
// =====================================================
DieSkillType::DieSkillType(){
skillClass= scDie;
}
void DieSkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt, const FactionType *ft){
SkillType::load(sn, dir, tt, ft);
fade= sn->getChild("fade")->getAttribute("value")->getBoolValue();
}
string DieSkillType::toString() const{
return "Die";
}
// =====================================================
// class SkillTypeFactory
// =====================================================
SkillTypeFactory::SkillTypeFactory(){
registerClass<StopSkillType>("stop");
registerClass<MoveSkillType>("move");
registerClass<AttackSkillType>("attack");
registerClass<BuildSkillType>("build");
registerClass<BeBuiltSkillType>("be_built");
registerClass<HarvestSkillType>("harvest");
registerClass<RepairSkillType>("repair");
registerClass<ProduceSkillType>("produce");
registerClass<UpgradeSkillType>("upgrade");
registerClass<MorphSkillType>("morph");
registerClass<DieSkillType>("die");
}
SkillTypeFactory &SkillTypeFactory::getInstance(){
static SkillTypeFactory ctf;
return ctf;
}
}} //end namespace

View File

@ -222,7 +222,8 @@ void UnitType::load(int id,const string &dir, const TechTree *techTree, const Fa
const XmlNode *particleFileNode= particleNode->getChild("particle-file", i);
string path= particleFileNode->getAttribute("path")->getRestrictedValue();
UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType();
unitParticleSystemType->load(dir, dir + "/" + path);
unitParticleSystemType->load(dir, dir + "/" + path, Renderer::getInstance().newTexture2D(rsGame));
damageParticleSystemTypes.push_back(unitParticleSystemType);
}
}