Updated with initial 3.4.4 codebase includes:
- network fixes for multiplayer defects found - initial code (disabled currently) for content crc checking and downloading - code compiles on Win32 using VS2008 express, project files not yet included
This commit is contained in:
parent
58ea5ec552
commit
fb5035c230
|
@ -1,11 +1,11 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -22,7 +22,7 @@ using namespace Shared::Util;
|
|||
namespace Glest{ namespace Game{
|
||||
|
||||
const string mailString= "contact_game@glest.org";
|
||||
const string glestVersionString= "v3.2.3";
|
||||
const string glestVersionString= "v3.2.4-4-beta1";
|
||||
|
||||
string getCrashDumpFileName(){
|
||||
return "glest"+glestVersionString+".dmp";
|
||||
|
@ -52,11 +52,11 @@ string getAboutString2(int i){
|
|||
|
||||
string getTeammateName(int i){
|
||||
switch(i){
|
||||
case 0: return "Marti<EFBFBD>o Figueroa";
|
||||
case 1: return "Jos<EFBFBD> Luis Gonz<6E>lez";
|
||||
case 2: return "Tucho Fern<EFBFBD>ndez";
|
||||
case 3: return "Jos<EFBFBD> Zanni";
|
||||
case 4: return "F<EFBFBD>lix Men<65>ndez";
|
||||
case 0: return "Martiño Figueroa";
|
||||
case 1: return "José Luis González";
|
||||
case 2: return "Tucho Fernández";
|
||||
case 3: return "José Zanni";
|
||||
case 4: return "Félix Menéndez";
|
||||
case 5: return "Marcos Caruncho";
|
||||
case 6: return "Matthias Braun";
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -40,7 +40,7 @@ void ChatManager::init(Console* console, int thisTeamIndex){
|
|||
}
|
||||
|
||||
void ChatManager::keyDown(char key){
|
||||
|
||||
|
||||
Lang &lang= Lang::getInstance();
|
||||
|
||||
//toggle team mode
|
||||
|
@ -86,18 +86,24 @@ void ChatManager::keyPress(char c){
|
|||
}
|
||||
}
|
||||
|
||||
void ChatManager::updateNetwork(){
|
||||
void ChatManager::updateNetwork()
|
||||
{
|
||||
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
|
||||
string text;
|
||||
string sender;
|
||||
|
||||
if(!gameNetworkInterface->getChatText().empty()){
|
||||
|
||||
if(!gameNetworkInterface->getChatText().empty())
|
||||
{
|
||||
int teamIndex= gameNetworkInterface->getChatTeamIndex();
|
||||
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtText [%s] for team = %d\n",__FILE__,__FUNCTION__,gameNetworkInterface->getChatText().c_str(),teamIndex);
|
||||
|
||||
if(teamIndex==-1 || teamIndex==thisTeamIndex){
|
||||
console->addLine(gameNetworkInterface->getChatSender()+": "+gameNetworkInterface->getChatText(), true);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] Added text to console\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -64,7 +64,7 @@ Game::~Game(){
|
|||
|
||||
logger.setState(Lang::getInstance().get("Deleting"));
|
||||
logger.add("Game", true);
|
||||
|
||||
|
||||
renderer.endGame();
|
||||
SoundRenderer::getInstance().stopAllSounds();
|
||||
|
||||
|
@ -75,7 +75,7 @@ Game::~Game(){
|
|||
}
|
||||
|
||||
|
||||
// ==================== init and load ====================
|
||||
// ==================== init and load ====================
|
||||
|
||||
void Game::load(){
|
||||
Logger &logger= Logger::getInstance();
|
||||
|
@ -83,7 +83,7 @@ void Game::load(){
|
|||
string tilesetName= gameSettings.getTileset();
|
||||
string techName= gameSettings.getTech();
|
||||
string scenarioName= gameSettings.getScenario();
|
||||
|
||||
|
||||
logger.setState(Lang::getInstance().get("Loading"));
|
||||
|
||||
if(scenarioName.empty()){
|
||||
|
@ -114,7 +114,10 @@ void Game::load(){
|
|||
}
|
||||
}
|
||||
|
||||
void Game::init(){
|
||||
void Game::init()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
Lang &lang= Lang::getInstance();
|
||||
Logger &logger= Logger::getInstance();
|
||||
CoreData &coreData= CoreData::getInstance();
|
||||
|
@ -122,8 +125,9 @@ void Game::init(){
|
|||
Map *map= world.getMap();
|
||||
NetworkManager &networkManager= NetworkManager::getInstance();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] Initializing\n",__FILE__,__FUNCTION__);
|
||||
logger.setState(lang.get("Initializing"));
|
||||
|
||||
|
||||
//mesage box
|
||||
mainMessageBox.init(lang.get("Yes"), lang.get("No"));
|
||||
mainMessageBox.setEnabled(false);
|
||||
|
@ -143,6 +147,8 @@ void Game::init(){
|
|||
gameCamera.setPos(Vec2f(v.x, v.y));
|
||||
scriptManager.init(&world, &gameCamera);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] creating AI's\n",__FILE__,__FUNCTION__);
|
||||
|
||||
//create IAs
|
||||
aiInterfaces.resize(world.getFactionCount());
|
||||
for(int i=0; i<world.getFactionCount(); ++i){
|
||||
|
@ -174,12 +180,13 @@ void Game::init(){
|
|||
}
|
||||
|
||||
//init renderer state
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] Initializing renderer\n",__FILE__,__FUNCTION__);
|
||||
logger.add("Initializing renderer", true);
|
||||
renderer.initGame(this);
|
||||
|
||||
//sounds
|
||||
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
|
||||
|
||||
|
||||
Tileset *tileset= world.getTileset();
|
||||
AmbientSounds *ambientSounds= tileset->getAmbientSounds();
|
||||
|
||||
|
@ -188,36 +195,40 @@ void Game::init(){
|
|||
logger.add("Starting ambient stream", true);
|
||||
soundRenderer.playAmbient(ambientSounds->getRain());
|
||||
}
|
||||
|
||||
|
||||
//snow
|
||||
if(tileset->getWeather()==wSnowy && ambientSounds->isEnabledSnow()){
|
||||
logger.add("Starting ambient stream", true);
|
||||
soundRenderer.playAmbient(ambientSounds->getSnow());
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] Waiting for network\n",__FILE__,__FUNCTION__);
|
||||
logger.add("Waiting for network", true);
|
||||
networkManager.getGameNetworkInterface()->waitUntilReady(&checksum);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] Starting music stream\n",__FILE__,__FUNCTION__);
|
||||
logger.add("Starting music stream", true);
|
||||
StrSound *gameMusic= world.getThisFaction()->getType()->getMusic();
|
||||
soundRenderer.playMusic(gameMusic);
|
||||
|
||||
logger.add("Launching game");
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
// ==================== update ====================
|
||||
// ==================== update ====================
|
||||
|
||||
//update
|
||||
void Game::update(){
|
||||
|
||||
|
||||
// a) Updates non dependant on speed
|
||||
|
||||
//misc
|
||||
updateFps++;
|
||||
mouse2d= (mouse2d+1) % Renderer::maxMouse2dAnim;
|
||||
|
||||
//console
|
||||
|
||||
//console
|
||||
console.update();
|
||||
|
||||
// b) Updates depandant on speed
|
||||
|
@ -231,7 +242,7 @@ void Game::update(){
|
|||
//AiInterface
|
||||
for(int i=0; i<world.getFactionCount(); ++i){
|
||||
if(world.getFaction(i)->getCpuControl() && scriptManager.getPlayerModifiers(i)->getAiEnabled()){
|
||||
aiInterfaces[i]->update();
|
||||
aiInterfaces[i]->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +254,7 @@ void Game::update(){
|
|||
|
||||
//Gui
|
||||
gui.update();
|
||||
|
||||
|
||||
//Particle systems
|
||||
if(weatherParticleSystem != NULL){
|
||||
weatherParticleSystem->setPos(gameCamera.getPos());
|
||||
|
@ -270,7 +281,7 @@ void Game::updateCamera(){
|
|||
}
|
||||
|
||||
|
||||
// ==================== render ====================
|
||||
// ==================== render ====================
|
||||
|
||||
//render
|
||||
void Game::render(){
|
||||
|
@ -280,7 +291,7 @@ void Game::render(){
|
|||
Renderer::getInstance().swapBuffers();
|
||||
}
|
||||
|
||||
// ==================== tick ====================
|
||||
// ==================== tick ====================
|
||||
|
||||
void Game::tick(){
|
||||
lastUpdateFps= updateFps;
|
||||
|
@ -294,7 +305,7 @@ void Game::tick(){
|
|||
}
|
||||
|
||||
|
||||
// ==================== events ====================
|
||||
// ==================== events ====================
|
||||
|
||||
void Game::mouseDownLeft(int x, int y){
|
||||
|
||||
|
@ -315,12 +326,12 @@ void Game::mouseDownLeft(int x, int y){
|
|||
//minimap panel
|
||||
if(!messageBoxClick){
|
||||
if(metrics.isInMinimap(x, y) && !gui.isSelectingPos()){
|
||||
|
||||
|
||||
int xm= x - metrics.getMinimapX();
|
||||
int ym= y - metrics.getMinimapY();
|
||||
int xCell= static_cast<int>(xm * (static_cast<float>(map->getW()) / metrics.getMinimapW()));
|
||||
int yCell= static_cast<int>(map->getH() - ym * (static_cast<float>(map->getH()) / metrics.getMinimapH()));
|
||||
|
||||
|
||||
if(map->isInside(xCell, yCell)){
|
||||
if(!gui.isSelectingPos()){
|
||||
gameCamera.setPos(Vec2f(static_cast<float>(xCell), static_cast<float>(yCell)));
|
||||
|
@ -333,13 +344,13 @@ void Game::mouseDownLeft(int x, int y){
|
|||
int xd= x - metrics.getDisplayX();
|
||||
int yd= y - metrics.getDisplayY();
|
||||
if(gui.mouseValid(xd, yd)){
|
||||
gui.mouseDownLeftDisplay(xd, yd);
|
||||
gui.mouseDownLeftDisplay(xd, yd);
|
||||
}
|
||||
else{
|
||||
gui.mouseDownLeftGraphics(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//graphics panel
|
||||
else{
|
||||
gui.mouseDownLeftGraphics(x, y);
|
||||
|
@ -349,12 +360,15 @@ void Game::mouseDownLeft(int x, int y){
|
|||
//exit message box, has to be the last thing to do in this function
|
||||
if(mainMessageBox.getEnabled()){
|
||||
int button= 1;
|
||||
if(mainMessageBox.mouseClick(x, y, button)){
|
||||
if(button==1){
|
||||
networkManager.getGameNetworkInterface()->quitGame();
|
||||
if(mainMessageBox.mouseClick(x, y, button))
|
||||
{
|
||||
if(button==1)
|
||||
{
|
||||
networkManager.getGameNetworkInterface()->quitGame(true);
|
||||
quitGame();
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
//close message box
|
||||
mainMessageBox.setEnabled(false);
|
||||
}
|
||||
|
@ -372,7 +386,7 @@ void Game::mouseUpLeft(int x, int y){
|
|||
|
||||
void Game::mouseDoubleClickLeft(int x, int y){
|
||||
const Metrics &metrics= Metrics::getInstance();
|
||||
|
||||
|
||||
//display panel
|
||||
if(metrics.isInDisplay(x, y) && !gui.isSelectingPos()){
|
||||
int xd= x - metrics.getDisplayX();
|
||||
|
@ -389,28 +403,28 @@ void Game::mouseDoubleClickLeft(int x, int y){
|
|||
void Game::mouseMove(int x, int y, const MouseState *ms){
|
||||
|
||||
const Metrics &metrics= Metrics::getInstance();
|
||||
|
||||
|
||||
mouseX= x;
|
||||
mouseY= y;
|
||||
|
||||
//main window
|
||||
if(y<10){
|
||||
if(y<10){
|
||||
gameCamera.setMoveZ(-1);
|
||||
}
|
||||
else if(y> metrics.getVirtualH()-10){
|
||||
else if(y> metrics.getVirtualH()-10){
|
||||
gameCamera.setMoveZ(1);
|
||||
}
|
||||
else{
|
||||
else{
|
||||
gameCamera.stopMoveZ();
|
||||
}
|
||||
|
||||
if(x<10){
|
||||
if(x<10){
|
||||
gameCamera.setMoveX(-1);
|
||||
}
|
||||
else if(x> metrics.getVirtualW()-10){
|
||||
else if(x> metrics.getVirtualW()-10){
|
||||
gameCamera.setMoveX(1);
|
||||
}
|
||||
else{
|
||||
else{
|
||||
gameCamera.stopMoveX();
|
||||
}
|
||||
|
||||
|
@ -449,7 +463,7 @@ void Game::keyDown(char key){
|
|||
else if(key=='E'){
|
||||
for(int i=0; i<100; ++i){
|
||||
string path= "screens/screen" + intToStr(i) + ".tga";
|
||||
|
||||
|
||||
FILE *f= fopen(path.c_str(), "rb");
|
||||
if(f==NULL){
|
||||
Renderer::getInstance().saveScreen(path);
|
||||
|
@ -592,9 +606,9 @@ void Game::quitGame(){
|
|||
program->setState(new BattleEnd(program, world.getStats()));
|
||||
}
|
||||
|
||||
// ==================== PRIVATE ====================
|
||||
// ==================== PRIVATE ====================
|
||||
|
||||
// ==================== render ====================
|
||||
// ==================== render ====================
|
||||
|
||||
void Game::render3d(){
|
||||
|
||||
|
@ -630,7 +644,7 @@ void Game::render3d(){
|
|||
|
||||
//particles
|
||||
renderer.renderParticleManager(rsGame);
|
||||
|
||||
|
||||
//mouse 3d
|
||||
renderer.renderMouse3d();
|
||||
}
|
||||
|
@ -642,10 +656,10 @@ void Game::render2d(){
|
|||
|
||||
//init
|
||||
renderer.reset2d();
|
||||
|
||||
|
||||
//display
|
||||
renderer.renderDisplay();
|
||||
|
||||
|
||||
//minimap
|
||||
if(!config.getBool("PhotoMode")){
|
||||
renderer.renderMinimap();
|
||||
|
@ -687,7 +701,7 @@ void Game::render2d(){
|
|||
str+= "Triangle count: "+intToStr(renderer.getTriangleCount())+"\n";
|
||||
str+= "Vertex count: "+intToStr(renderer.getPointCount())+"\n";
|
||||
str+= "Frame count:"+intToStr(world.getFrameCount())+"\n";
|
||||
|
||||
|
||||
//visible quad
|
||||
Quad2i visibleQuad= renderer.getVisibleQuad();
|
||||
|
||||
|
@ -716,7 +730,7 @@ void Game::render2d(){
|
|||
//network status
|
||||
if(renderNetworkStatus){
|
||||
renderer.renderText(
|
||||
NetworkManager::getInstance().getGameNetworkInterface()->getNetworkStatus(),
|
||||
NetworkManager::getInstance().getGameNetworkInterface()->getNetworkStatus(),
|
||||
coreData.getMenuFontNormal(),
|
||||
Vec3f(1.0f), 20, 500, false);
|
||||
}
|
||||
|
@ -726,15 +740,15 @@ void Game::render2d(){
|
|||
renderer.renderResourceStatus();
|
||||
renderer.renderConsole(&console);
|
||||
}
|
||||
|
||||
|
||||
//2d mouse
|
||||
renderer.renderMouse2d(mouseX, mouseY, mouse2d, gui.isSelectingPos()? 1.f: 0.f);
|
||||
}
|
||||
|
||||
|
||||
// ==================== misc ====================
|
||||
// ==================== misc ====================
|
||||
|
||||
void Game::checkWinner(){
|
||||
void Game::checkWinner(){
|
||||
if(!gameOver){
|
||||
if(gameSettings.getDefaultVictoryConditions()){
|
||||
checkWinnerStandard();
|
||||
|
@ -753,7 +767,7 @@ void Game::checkWinnerStandard(){
|
|||
lose= true;
|
||||
for(int i=0; i<world.getFactionCount(); ++i){
|
||||
if(!world.getFaction(i)->isAlly(world.getThisFaction())){
|
||||
world.getStats()->setVictorious(i);
|
||||
world.getStats()->setVictorious(i);
|
||||
}
|
||||
}
|
||||
gameOver= true;
|
||||
|
@ -775,7 +789,7 @@ void Game::checkWinnerStandard(){
|
|||
if(win){
|
||||
for(int i=0; i< world.getFactionCount(); ++i){
|
||||
if(world.getFaction(i)->isAlly(world.getThisFaction())){
|
||||
world.getStats()->setVictorious(i);
|
||||
world.getStats()->setVictorious(i);
|
||||
}
|
||||
}
|
||||
gameOver= true;
|
||||
|
@ -789,7 +803,7 @@ void Game::checkWinnerScripted(){
|
|||
gameOver= true;
|
||||
for(int i= 0; i<world.getFactionCount(); ++i){
|
||||
if(scriptManager.getPlayerModifiers(i)->getWinner()){
|
||||
world.getStats()->setVictorious(i);
|
||||
world.getStats()->setVictorious(i);
|
||||
}
|
||||
}
|
||||
if(scriptManager.getPlayerModifiers(world.getThisFactionIndex())->getWinner()){
|
||||
|
@ -869,7 +883,7 @@ void Game::showMessageBox(const string &text, const string &header, bool toggle)
|
|||
if(!toggle){
|
||||
mainMessageBox.setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
if(!mainMessageBox.getEnabled()){
|
||||
mainMessageBox.setText(text);
|
||||
mainMessageBox.setHeader(header);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -41,7 +41,50 @@ private:
|
|||
bool defaultResources;
|
||||
bool defaultVictoryConditions;
|
||||
|
||||
public:
|
||||
void CopyAll(const GameSettings &game)
|
||||
{
|
||||
description = game.description;
|
||||
map = game.map;
|
||||
tileset = game.tileset;
|
||||
tech = game.tech;
|
||||
scenario = game.scenario;
|
||||
scenarioDir = game.scenarioDir;
|
||||
thisFactionIndex = game.thisFactionIndex;
|
||||
factionCount = game.factionCount;
|
||||
defaultUnits = game.defaultUnits;
|
||||
defaultResources = game.defaultResources;
|
||||
defaultVictoryConditions = game.defaultVictoryConditions;
|
||||
|
||||
for(int i = 0; i < GameConstants::maxPlayers; i++)
|
||||
{
|
||||
factionTypeNames[i] = game.factionTypeNames[i]; //faction names
|
||||
factionControls[i] = game.factionControls[i];
|
||||
teams[i] = game.teams[i];
|
||||
startLocationIndex[i] = game.startLocationIndex[i];
|
||||
}
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] gameSettings->getTileset() = [%s]\n",__FILE__,__FUNCTION__,getTileset().c_str());
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] gameSettings->getTech() = [%s]\n",__FILE__,__FUNCTION__,getTech().c_str());
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] gameSettings->getMap() = [%s]\n",__FILE__,__FUNCTION__,getMap().c_str());
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
GameSettings() { }
|
||||
|
||||
GameSettings(const GameSettings &game)
|
||||
{
|
||||
CopyAll(game);
|
||||
}
|
||||
|
||||
GameSettings & operator=(const GameSettings &game)
|
||||
{
|
||||
CopyAll(game);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//get
|
||||
const string &getDescription() const {return description;}
|
||||
const string &getMap() const {return map;}
|
||||
|
@ -53,7 +96,7 @@ public:
|
|||
ControlType getFactionControl(int factionIndex) const {return factionControls[factionIndex];}
|
||||
|
||||
int getThisFactionIndex() const {return thisFactionIndex;}
|
||||
int getFactionCount() const {return factionCount;}
|
||||
int getFactionCount() const {return factionCount;}
|
||||
int getTeam(int factionIndex) const {return teams[factionIndex];}
|
||||
int getStartLocationIndex(int factionIndex) const {return startLocationIndex[factionIndex];}
|
||||
|
||||
|
@ -74,7 +117,7 @@ public:
|
|||
void setFactionControl(int factionIndex, ControlType controller) {this->factionControls[factionIndex]= controller;}
|
||||
|
||||
void setThisFactionIndex(int thisFactionIndex) {this->thisFactionIndex= thisFactionIndex;}
|
||||
void setFactionCount(int factionCount) {this->factionCount= factionCount;}
|
||||
void setFactionCount(int factionCount) {this->factionCount= factionCount;}
|
||||
void setTeam(int factionIndex, int team) {this->teams[factionIndex]= team;}
|
||||
void setStartLocationIndex(int factionIndex, int startLocationIndex) {this->startLocationIndex[factionIndex]= startLocationIndex;}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -41,7 +41,7 @@ namespace Glest{ namespace Game{
|
|||
|
||||
const int Program::maxTimes= 10;
|
||||
|
||||
// ===================== PUBLIC ========================
|
||||
// ===================== PUBLIC ========================
|
||||
|
||||
Program::Program(){
|
||||
programState= NULL;
|
||||
|
@ -54,7 +54,7 @@ void Program::initNormal(WindowGl *window){
|
|||
|
||||
void Program::initServer(WindowGl *window){
|
||||
MainMenu* mainMenu= NULL;
|
||||
|
||||
|
||||
init(window);
|
||||
mainMenu= new MainMenu(this);
|
||||
setState(mainMenu);
|
||||
|
@ -63,7 +63,7 @@ void Program::initServer(WindowGl *window){
|
|||
|
||||
void Program::initClient(WindowGl *window, const Ip &serverIp){
|
||||
MainMenu* mainMenu= NULL;
|
||||
|
||||
|
||||
init(window);
|
||||
mainMenu= new MainMenu(this);
|
||||
setState(mainMenu);
|
||||
|
@ -72,14 +72,14 @@ void Program::initClient(WindowGl *window, const Ip &serverIp){
|
|||
|
||||
Program::~Program(){
|
||||
delete programState;
|
||||
|
||||
|
||||
Renderer::getInstance().end();
|
||||
|
||||
|
||||
//restore video mode
|
||||
restoreDisplaySettings();
|
||||
}
|
||||
|
||||
void Program::mouseDownLeft(int x, int y){
|
||||
void Program::mouseDownLeft(int x, int y){
|
||||
const Metrics &metrics= Metrics::getInstance();
|
||||
programState->mouseDownLeft(metrics.toVirtualX(x), metrics.toVirtualY(y));
|
||||
}
|
||||
|
@ -91,12 +91,12 @@ void Program::mouseUpLeft(int x, int y){
|
|||
|
||||
void Program::mouseDownRight(int x, int y){
|
||||
const Metrics &metrics= Metrics::getInstance();
|
||||
programState->mouseDownRight(metrics.toVirtualX(x), metrics.toVirtualY(y));
|
||||
programState->mouseDownRight(metrics.toVirtualX(x), metrics.toVirtualY(y));
|
||||
}
|
||||
|
||||
void Program::mouseDoubleClickLeft(int x, int y){
|
||||
const Metrics &metrics= Metrics::getInstance();
|
||||
programState->mouseDoubleClickLeft(metrics.toVirtualX(x), metrics.toVirtualY(y));
|
||||
programState->mouseDoubleClickLeft(metrics.toVirtualX(x), metrics.toVirtualY(y));
|
||||
}
|
||||
|
||||
void Program::mouseMove(int x, int y, const MouseState *ms){
|
||||
|
@ -109,7 +109,7 @@ void Program::keyDown(char key){
|
|||
programState->keyDown(key);
|
||||
}
|
||||
|
||||
void Program::keyUp(char key){
|
||||
void Program::keyUp(char key){
|
||||
programState->keyUp(key);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ void Program::loop(){
|
|||
SoundRenderer::getInstance().update();
|
||||
NetworkManager::getInstance().update();
|
||||
}
|
||||
|
||||
|
||||
//fps timer
|
||||
while(fpsTimer.isTime()){
|
||||
programState->tick();
|
||||
|
@ -142,7 +142,7 @@ void Program::loop(){
|
|||
}
|
||||
|
||||
void Program::resize(SizeState sizeState){
|
||||
|
||||
|
||||
switch(sizeState){
|
||||
case ssMinimized:
|
||||
//restoreVideoMode();
|
||||
|
@ -155,32 +155,44 @@ void Program::resize(SizeState sizeState){
|
|||
}
|
||||
}
|
||||
|
||||
// ==================== misc ====================
|
||||
// ==================== misc ====================
|
||||
|
||||
void Program::setState(ProgramState *programState)
|
||||
{
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
void Program::setState(ProgramState *programState){
|
||||
|
||||
delete this->programState;
|
||||
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] A\n",__FILE__,__FUNCTION__);
|
||||
|
||||
this->programState= programState;
|
||||
programState->load();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] B\n",__FILE__,__FUNCTION__);
|
||||
|
||||
programState->init();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] C\n",__FILE__,__FUNCTION__);
|
||||
|
||||
updateTimer.reset();
|
||||
updateCameraTimer.reset();
|
||||
fpsTimer.reset();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
void Program::exit(){
|
||||
window->destroy();
|
||||
}
|
||||
|
||||
// ==================== PRIVATE ====================
|
||||
// ==================== PRIVATE ====================
|
||||
|
||||
void Program::init(WindowGl *window){
|
||||
|
||||
this->window= window;
|
||||
Config &config= Config::getInstance();
|
||||
|
||||
|
||||
//set video mode
|
||||
setDisplaySettings();
|
||||
|
||||
|
@ -190,7 +202,7 @@ void Program::init(WindowGl *window){
|
|||
window->setPos(0, 0);
|
||||
window->setSize(config.getInt("ScreenWidth"), config.getInt("ScreenHeight"));
|
||||
window->create();
|
||||
|
||||
|
||||
//timers
|
||||
fpsTimer.init(1, maxTimes);
|
||||
updateTimer.init(GameConstants::updateFps, maxTimes);
|
||||
|
@ -204,13 +216,13 @@ void Program::init(WindowGl *window){
|
|||
//lang
|
||||
Lang &lang= Lang::getInstance();
|
||||
lang.loadStrings(config.getString("Lang"));
|
||||
|
||||
|
||||
//render
|
||||
Renderer &renderer= Renderer::getInstance();
|
||||
|
||||
window->initGl(config.getInt("ColorBits"), config.getInt("DepthBits"), config.getInt("StencilBits"));
|
||||
window->makeCurrentGl();
|
||||
|
||||
|
||||
//coreData, needs renderer, but must load before renderer init
|
||||
CoreData &coreData= CoreData::getInstance();
|
||||
coreData.load();
|
||||
|
@ -226,29 +238,29 @@ void Program::init(WindowGl *window){
|
|||
void Program::setDisplaySettings(){
|
||||
|
||||
Config &config= Config::getInstance();
|
||||
|
||||
|
||||
if(!config.getBool("Windowed")){
|
||||
|
||||
|
||||
int freq= config.getInt("RefreshFrequency");
|
||||
int colorBits= config.getInt("ColorBits");
|
||||
int screenWidth= config.getInt("ScreenWidth");
|
||||
int screenHeight= config.getInt("ScreenHeight");
|
||||
|
||||
|
||||
if(!(changeVideoMode(screenWidth, screenHeight, colorBits, freq) ||
|
||||
changeVideoMode(screenWidth, screenHeight, colorBits, 0)))
|
||||
{
|
||||
throw runtime_error(
|
||||
"Error setting video mode: " +
|
||||
"Error setting video mode: " +
|
||||
intToStr(screenWidth) + "x" + intToStr(screenHeight) + "x" + intToStr(colorBits));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Program::restoreDisplaySettings(){
|
||||
Config &config= Config::getInstance();
|
||||
|
||||
|
||||
if(!config.getBool("Windowed")){
|
||||
restoreVideoMode();
|
||||
restoreVideoMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2005 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2005 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include "game.h"
|
||||
|
||||
#include "leak_dumper.h"
|
||||
#include <time.h>
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
|
@ -34,12 +35,15 @@ using namespace Shared::Util;
|
|||
// class MenuStateCustomGame
|
||||
// =====================================================
|
||||
|
||||
MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, bool openNetworkSlots):
|
||||
MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, bool openNetworkSlots):
|
||||
MenuState(program, mainMenu, "new-game")
|
||||
{
|
||||
Lang &lang= Lang::getInstance();
|
||||
NetworkManager &networkManager= NetworkManager::getInstance();
|
||||
|
||||
needToSetChangedGameSettings = false;
|
||||
lastSetChangedGameSettings = time(NULL);;
|
||||
|
||||
vector<string> results, teamItems, controlItems;
|
||||
|
||||
//create
|
||||
|
@ -121,12 +125,12 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
|
|||
if(results.size()==0){
|
||||
throw runtime_error("There is no factions for this tech tree");
|
||||
}
|
||||
|
||||
|
||||
for(int i=0; i<GameConstants::maxPlayers; ++i){
|
||||
labelPlayers[i].setText(lang.get("Player")+" "+intToStr(i));
|
||||
listBoxTeams[i].setItems(teamItems);
|
||||
listBoxTeams[i].setSelectedItemIndex(i);
|
||||
listBoxControls[i].setItems(controlItems);
|
||||
listBoxControls[i].setItems(controlItems);
|
||||
labelNetStatus[i].setText("");
|
||||
}
|
||||
|
||||
|
@ -138,7 +142,7 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
|
|||
labelTeam.setText(lang.get("Team"));
|
||||
|
||||
loadMapInfo(Map::getMapPath(mapFiles[listBoxMap.getSelectedItemIndex()]), &mapInfo);
|
||||
|
||||
|
||||
labelMapInfo.setText(mapInfo.desc);
|
||||
|
||||
//initialize network interface
|
||||
|
@ -156,6 +160,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
|
|||
}
|
||||
updateControlers();
|
||||
updateNetworkSlots();
|
||||
|
||||
//chatManager.init(&console, world.getThisTeamIndex());
|
||||
chatManager.init(&console, -1);
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
|
||||
|
@ -167,31 +174,67 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
|
|||
if(buttonReturn.mouseClick(x,y)){
|
||||
soundRenderer.playFx(coreData.getClickSoundA());
|
||||
mainMenu->setState(new MenuStateNewGame(program, mainMenu));
|
||||
}
|
||||
else if(buttonPlayNow.mouseClick(x,y)){
|
||||
GameSettings gameSettings;
|
||||
|
||||
}
|
||||
else if(buttonPlayNow.mouseClick(x,y) && buttonPlayNow.getEnabled()) {
|
||||
|
||||
closeUnusedSlots();
|
||||
soundRenderer.playFx(coreData.getClickSoundC());
|
||||
|
||||
GameSettings gameSettings;
|
||||
loadGameSettings(&gameSettings);
|
||||
serverInterface->launchGame(&gameSettings);
|
||||
program->setState(new Game(program, &gameSettings));
|
||||
|
||||
// Send the game settings to each client if we have at least one networked client
|
||||
if( hasNetworkGameSettings() == true &&
|
||||
needToSetChangedGameSettings == true)
|
||||
{
|
||||
serverInterface->setGameSettings(&gameSettings,true);
|
||||
|
||||
needToSetChangedGameSettings = false;
|
||||
lastSetChangedGameSettings = time(NULL);
|
||||
}
|
||||
|
||||
bool bOkToStart = serverInterface->launchGame(&gameSettings);
|
||||
if(bOkToStart == true)
|
||||
{
|
||||
|
||||
program->setState(new Game(program, &gameSettings));
|
||||
}
|
||||
}
|
||||
else if(listBoxMap.mouseClick(x, y)){
|
||||
loadMapInfo(Map::getMapPath(mapFiles[listBoxMap.getSelectedItemIndex()]), &mapInfo);
|
||||
labelMapInfo.setText(mapInfo.desc);
|
||||
updateControlers();
|
||||
|
||||
if(hasNetworkGameSettings() == true)
|
||||
{
|
||||
needToSetChangedGameSettings = true;
|
||||
lastSetChangedGameSettings = time(NULL);;
|
||||
}
|
||||
}
|
||||
else if(listBoxTileset.mouseClick(x, y)){
|
||||
|
||||
if(hasNetworkGameSettings() == true)
|
||||
{
|
||||
needToSetChangedGameSettings = true;
|
||||
lastSetChangedGameSettings = time(NULL);;
|
||||
}
|
||||
}
|
||||
else if(listBoxTechTree.mouseClick(x, y)){
|
||||
reloadFactions();
|
||||
}
|
||||
else{
|
||||
for(int i=0; i<mapInfo.players; ++i){
|
||||
//ensure thet only 1 human player is present
|
||||
if(listBoxControls[i].mouseClick(x, y)){
|
||||
|
||||
if(hasNetworkGameSettings() == true)
|
||||
{
|
||||
needToSetChangedGameSettings = true;
|
||||
lastSetChangedGameSettings = time(NULL);;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i=0; i<mapInfo.players; ++i)
|
||||
{
|
||||
//ensure thet only 1 human player is present
|
||||
if(listBoxControls[i].mouseClick(x, y))
|
||||
{
|
||||
//look for human players
|
||||
int humanIndex1= -1;
|
||||
int humanIndex2= -1;
|
||||
|
@ -217,17 +260,35 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
|
|||
listBoxControls[humanIndex1==i? humanIndex2: humanIndex1].setSelectedItemIndex(ctClosed);
|
||||
}
|
||||
updateNetworkSlots();
|
||||
|
||||
if(hasNetworkGameSettings() == true)
|
||||
{
|
||||
needToSetChangedGameSettings = true;
|
||||
lastSetChangedGameSettings = time(NULL);;
|
||||
}
|
||||
}
|
||||
else if(listBoxFactions[i].mouseClick(x, y)){
|
||||
|
||||
if(hasNetworkGameSettings() == true)
|
||||
{
|
||||
needToSetChangedGameSettings = true;
|
||||
lastSetChangedGameSettings = time(NULL);;
|
||||
}
|
||||
}
|
||||
else if(listBoxTeams[i].mouseClick(x, y)){
|
||||
else if(listBoxTeams[i].mouseClick(x, y))
|
||||
{
|
||||
if(hasNetworkGameSettings() == true)
|
||||
{
|
||||
needToSetChangedGameSettings = true;
|
||||
lastSetChangedGameSettings = time(NULL);;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::mouseMove(int x, int y, const MouseState *ms){
|
||||
|
||||
|
||||
buttonReturn.mouseMove(x, y);
|
||||
buttonPlayNow.mouseMove(x, y);
|
||||
|
||||
|
@ -270,33 +331,131 @@ void MenuStateCustomGame::render(){
|
|||
renderer.renderListBox(&listBoxMap);
|
||||
renderer.renderListBox(&listBoxTileset);
|
||||
renderer.renderListBox(&listBoxTechTree);
|
||||
|
||||
renderer.renderChatManager(&chatManager);
|
||||
renderer.renderConsole(&console);
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::update(){
|
||||
void MenuStateCustomGame::update()
|
||||
{
|
||||
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
|
||||
Lang& lang= Lang::getInstance();
|
||||
|
||||
for(int i= 0; i<mapInfo.players; ++i){
|
||||
if(listBoxControls[i].getSelectedItemIndex()==ctNetwork){
|
||||
bool haveAtLeastOneNetworkClientConnected = false;
|
||||
|
||||
for(int i= 0; i<mapInfo.players; ++i)
|
||||
{
|
||||
if(listBoxControls[i].getSelectedItemIndex() == ctNetwork)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] START - ctNetwork\n",__FILE__,__FUNCTION__);
|
||||
|
||||
ConnectionSlot* connectionSlot= serverInterface->getSlot(i);
|
||||
|
||||
assert(connectionSlot!=NULL);
|
||||
|
||||
if(connectionSlot->isConnected()){
|
||||
labelNetStatus[i].setText(connectionSlot->getName());
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] A - ctNetwork\n",__FILE__,__FUNCTION__);
|
||||
|
||||
if(connectionSlot->isConnected())
|
||||
{
|
||||
haveAtLeastOneNetworkClientConnected = true;
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] B - ctNetwork\n",__FILE__,__FUNCTION__);
|
||||
|
||||
string label = connectionSlot->getName();
|
||||
if(connectionSlot->getAllowDownloadDataSynch() == true &&
|
||||
connectionSlot->getAllowGameDataSynchCheck() == true)
|
||||
{
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOk() == false)
|
||||
{
|
||||
label = connectionSlot->getName() + " - waiting to synch:";
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkMap() == false)
|
||||
{
|
||||
label = label + " map";
|
||||
}
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkTile() == false)
|
||||
{
|
||||
label = label + " tile";
|
||||
}
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkTech() == false)
|
||||
{
|
||||
label = label + " techtree";
|
||||
}
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkFogOfWar() == false)
|
||||
{
|
||||
label = label + " FogOfWar == false";
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
label = connectionSlot->getName() + " - data synch is ok";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label = connectionSlot->getName();
|
||||
|
||||
if(connectionSlot->getAllowGameDataSynchCheck() == true)
|
||||
{
|
||||
label += " - warning synch mismatch for:";
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkMap() == false)
|
||||
{
|
||||
label = label + " map";
|
||||
}
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkTile() == false)
|
||||
{
|
||||
label = label + " tile";
|
||||
}
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkTech() == false)
|
||||
{
|
||||
label = label + " techtree";
|
||||
}
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOkFogOfWar() == false)
|
||||
{
|
||||
label = label + " FogOfWar == false";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
labelNetStatus[i].setText(label);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] C - ctNetwork\n",__FILE__,__FUNCTION__);
|
||||
|
||||
labelNetStatus[i].setText(lang.get("NotConnected"));
|
||||
}
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] END - ctNetwork\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
else{
|
||||
labelNetStatus[i].setText("");
|
||||
}
|
||||
}
|
||||
|
||||
// Send the game settings to each client if we have at least one networked client
|
||||
if( serverInterface->getAllowDownloadDataSynch() == true &&
|
||||
haveAtLeastOneNetworkClientConnected == true &&
|
||||
needToSetChangedGameSettings == true &&
|
||||
difftime(time(NULL),lastSetChangedGameSettings) >= 2)
|
||||
{
|
||||
GameSettings gameSettings;
|
||||
loadGameSettings(&gameSettings);
|
||||
serverInterface->setGameSettings(&gameSettings);
|
||||
|
||||
needToSetChangedGameSettings = false;
|
||||
lastSetChangedGameSettings = time(NULL);
|
||||
}
|
||||
|
||||
//call the chat manager
|
||||
chatManager.updateNetwork();
|
||||
|
||||
//console
|
||||
console.update();
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings){
|
||||
void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
int factionCount= 0;
|
||||
|
||||
|
@ -307,11 +466,14 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings){
|
|||
gameSettings->setDefaultUnits(true);
|
||||
gameSettings->setDefaultResources(true);
|
||||
gameSettings->setDefaultVictoryConditions(true);
|
||||
|
||||
for(int i=0; i<mapInfo.players; ++i){
|
||||
|
||||
for(int i=0; i<mapInfo.players; ++i)
|
||||
{
|
||||
ControlType ct= static_cast<ControlType>(listBoxControls[i].getSelectedItemIndex());
|
||||
if(ct!=ctClosed){
|
||||
if(ct==ctHuman){
|
||||
if(ct != ctClosed)
|
||||
{
|
||||
if(ct == ctHuman)
|
||||
{
|
||||
gameSettings->setThisFactionIndex(factionCount);
|
||||
}
|
||||
gameSettings->setFactionControl(factionCount, ct);
|
||||
|
@ -322,10 +484,36 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings){
|
|||
}
|
||||
}
|
||||
gameSettings->setFactionCount(factionCount);
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] gameSettings->getTileset() = [%s]\n",__FILE__,__FUNCTION__,gameSettings->getTileset().c_str());
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] gameSettings->getTech() = [%s]\n",__FILE__,__FUNCTION__,gameSettings->getTech().c_str());
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] gameSettings->getMap() = [%s]\n",__FILE__,__FUNCTION__,gameSettings->getMap().c_str());
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
// ============ PRIVATE ===========================
|
||||
|
||||
bool MenuStateCustomGame::hasNetworkGameSettings()
|
||||
{
|
||||
bool hasNetworkSlot = false;
|
||||
|
||||
for(int i=0; i<mapInfo.players; ++i)
|
||||
{
|
||||
ControlType ct= static_cast<ControlType>(listBoxControls[i].getSelectedItemIndex());
|
||||
if(ct != ctClosed)
|
||||
{
|
||||
if(ct == ctNetwork)
|
||||
{
|
||||
hasNetworkSlot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasNetworkSlot;
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::loadMapInfo(string file, MapInfo *mapInfo){
|
||||
|
||||
struct MapFileHeader{
|
||||
|
@ -364,7 +552,7 @@ void MenuStateCustomGame::loadMapInfo(string file, MapInfo *mapInfo){
|
|||
}
|
||||
|
||||
void MenuStateCustomGame::reloadFactions(){
|
||||
|
||||
|
||||
vector<string> results;
|
||||
|
||||
findAll("techs/"+techTreeFiles[listBoxTechTree.getSelectedItemIndex()]+"/factions/*.", results);
|
||||
|
@ -383,7 +571,7 @@ void MenuStateCustomGame::reloadFactions(){
|
|||
|
||||
void MenuStateCustomGame::updateControlers(){
|
||||
bool humanPlayer= false;
|
||||
|
||||
|
||||
for(int i= 0; i<mapInfo.players; ++i){
|
||||
if(listBoxControls[i].getSelectedItemIndex() == ctHuman){
|
||||
humanPlayer= true;
|
||||
|
@ -411,17 +599,33 @@ void MenuStateCustomGame::closeUnusedSlots(){
|
|||
updateNetworkSlots();
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::updateNetworkSlots(){
|
||||
void MenuStateCustomGame::updateNetworkSlots()
|
||||
{
|
||||
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
if(serverInterface->getSlot(i)==NULL && listBoxControls[i].getSelectedItemIndex()==ctNetwork){
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
if(serverInterface->getSlot(i) == NULL && listBoxControls[i].getSelectedItemIndex() == ctNetwork)
|
||||
{
|
||||
serverInterface->addSlot(i);
|
||||
}
|
||||
if(serverInterface->getSlot(i) != NULL && listBoxControls[i].getSelectedItemIndex()!=ctNetwork){
|
||||
if(serverInterface->getSlot(i) != NULL && listBoxControls[i].getSelectedItemIndex() != ctNetwork)
|
||||
{
|
||||
serverInterface->removeSlot(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::keyDown(char key)
|
||||
{
|
||||
//send key to the chat manager
|
||||
chatManager.keyDown(key);
|
||||
}
|
||||
|
||||
void MenuStateCustomGame::keyPress(char c)
|
||||
{
|
||||
chatManager.keyPress(c);
|
||||
}
|
||||
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2005 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -13,11 +13,12 @@
|
|||
#define _GLEST_GAME_MENUSTATECUSTOMGAME_H_
|
||||
|
||||
#include "main_menu.h"
|
||||
#include "chat_manager.h"
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
// ===============================
|
||||
// class MenuStateCustomGame
|
||||
// class MenuStateCustomGame
|
||||
// ===============================
|
||||
|
||||
class MenuStateCustomGame: public MenuState{
|
||||
|
@ -45,6 +46,12 @@ private:
|
|||
GraphicLabel labelNetStatus[GameConstants::maxPlayers];
|
||||
MapInfo mapInfo;
|
||||
|
||||
bool needToSetChangedGameSettings;
|
||||
time_t lastSetChangedGameSettings;
|
||||
|
||||
Console console;
|
||||
ChatManager chatManager;
|
||||
|
||||
public:
|
||||
MenuStateCustomGame(Program *program, MainMenu *mainMenu, bool openNetworkSlots= false);
|
||||
|
||||
|
@ -53,7 +60,12 @@ public:
|
|||
void render();
|
||||
void update();
|
||||
|
||||
virtual void keyDown(char key);
|
||||
virtual void keyPress(char c);
|
||||
|
||||
private:
|
||||
|
||||
bool hasNetworkGameSettings();
|
||||
void loadGameSettings(GameSettings *gameSettings);
|
||||
void loadMapInfo(string file, MapInfo *mapInfo);
|
||||
void reloadFactions();
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2005 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace Glest{ namespace Game{
|
|||
using namespace Shared::Util;
|
||||
|
||||
// ===============================
|
||||
// class MenuStateJoinGame
|
||||
// class MenuStateJoinGame
|
||||
// ===============================
|
||||
|
||||
const int MenuStateJoinGame::newServerIndex= 0;
|
||||
|
@ -87,7 +87,8 @@ MenuStateJoinGame::MenuStateJoinGame(Program *program, MainMenu *mainMenu, bool
|
|||
playerIndex= -1;
|
||||
|
||||
//server ip
|
||||
if(connect){
|
||||
if(connect)
|
||||
{
|
||||
labelServerIp.setText(serverIp.getString() + "_");
|
||||
connectToServer();
|
||||
}
|
||||
|
@ -95,9 +96,13 @@ MenuStateJoinGame::MenuStateJoinGame(Program *program, MainMenu *mainMenu, bool
|
|||
{
|
||||
labelServerIp.setText(config.getString("ServerIp") + "_");
|
||||
}
|
||||
|
||||
chatManager.init(&console, -1);
|
||||
}
|
||||
|
||||
void MenuStateJoinGame::mouseClick(int x, int y, MouseButton mouseButton){
|
||||
void MenuStateJoinGame::mouseClick(int x, int y, MouseButton mouseButton)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
CoreData &coreData= CoreData::getInstance();
|
||||
SoundRenderer &soundRenderer= SoundRenderer::getInstance();
|
||||
|
@ -121,25 +126,42 @@ void MenuStateJoinGame::mouseClick(int x, int y, MouseButton mouseButton){
|
|||
}
|
||||
|
||||
//return
|
||||
if(buttonReturn.mouseClick(x, y)){
|
||||
if(buttonReturn.mouseClick(x, y))
|
||||
{
|
||||
soundRenderer.playFx(coreData.getClickSoundA());
|
||||
|
||||
if(clientInterface->getSocket() != NULL)
|
||||
{
|
||||
if(clientInterface->isConnected() == true)
|
||||
{
|
||||
string sQuitText = clientInterface->getHostName() + " has chosen to leave the game!";
|
||||
clientInterface->sendTextMessage(sQuitText,-1);
|
||||
}
|
||||
clientInterface->close();
|
||||
}
|
||||
|
||||
mainMenu->setState(new MenuStateRoot(program, mainMenu));
|
||||
}
|
||||
}
|
||||
|
||||
//connect
|
||||
else if(buttonConnect.mouseClick(x, y)){
|
||||
else if(buttonConnect.mouseClick(x, y))
|
||||
{
|
||||
ClientInterface* clientInterface= networkManager.getClientInterface();
|
||||
|
||||
soundRenderer.playFx(coreData.getClickSoundA());
|
||||
labelInfo.setText("");
|
||||
|
||||
if(clientInterface->isConnected()){
|
||||
|
||||
if(clientInterface->isConnected())
|
||||
{
|
||||
clientInterface->reset();
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
connectToServer();
|
||||
}
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void MenuStateJoinGame::mouseMove(int x, int y, const MouseState *ms){
|
||||
|
@ -166,7 +188,7 @@ void MenuStateJoinGame::render(){
|
|||
renderer.renderLabel(&labelInfo);
|
||||
renderer.renderButton(&buttonConnect);
|
||||
renderer.renderListBox(&listBoxServerType);
|
||||
|
||||
|
||||
if(listBoxServerType.getSelectedItemIndex()==newServerIndex){
|
||||
renderer.renderLabel(&labelServerIp);
|
||||
}
|
||||
|
@ -174,52 +196,145 @@ void MenuStateJoinGame::render(){
|
|||
{
|
||||
renderer.renderListBox(&listBoxServers);
|
||||
}
|
||||
|
||||
renderer.renderChatManager(&chatManager);
|
||||
renderer.renderConsole(&console);
|
||||
}
|
||||
|
||||
void MenuStateJoinGame::update(){
|
||||
void MenuStateJoinGame::update()
|
||||
{
|
||||
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
||||
Lang &lang= Lang::getInstance();
|
||||
|
||||
//update status label
|
||||
if(clientInterface->isConnected()){
|
||||
if(clientInterface->isConnected())
|
||||
{
|
||||
buttonConnect.setText(lang.get("Disconnect"));
|
||||
if(!clientInterface->getServerName().empty()){
|
||||
labelStatus.setText(lang.get("ConnectedToServer") + " " + clientInterface->getServerName());
|
||||
|
||||
if(clientInterface->getAllowDownloadDataSynch() == false)
|
||||
{
|
||||
string label = lang.get("ConnectedToServer");
|
||||
|
||||
if(!clientInterface->getServerName().empty())
|
||||
{
|
||||
label = label + " " + clientInterface->getServerName();
|
||||
}
|
||||
|
||||
if(clientInterface->getAllowGameDataSynchCheck() == true &&
|
||||
clientInterface->getNetworkGameDataSynchCheckOk() == false)
|
||||
{
|
||||
label = label + " - warning synch mismatch for:";
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkMap() == false)
|
||||
{
|
||||
label = label + " map";
|
||||
}
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkTile() == false)
|
||||
{
|
||||
label = label + " tile";
|
||||
}
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkTech() == false)
|
||||
{
|
||||
label = label + " techtree";
|
||||
}
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkFogOfWar() == false)
|
||||
{
|
||||
label = label + " FogOfWar == false";
|
||||
}
|
||||
}
|
||||
else if(clientInterface->getAllowGameDataSynchCheck() == true)
|
||||
{
|
||||
label += " - data synch is ok";
|
||||
}
|
||||
|
||||
labelStatus.setText(label);
|
||||
}
|
||||
else{
|
||||
labelStatus.setText(lang.get("ConnectedToServer"));
|
||||
else
|
||||
{
|
||||
string label = lang.get("ConnectedToServer");
|
||||
|
||||
if(!clientInterface->getServerName().empty())
|
||||
{
|
||||
label = label + " " + clientInterface->getServerName();
|
||||
}
|
||||
|
||||
if(clientInterface->getAllowGameDataSynchCheck() == true &&
|
||||
clientInterface->getNetworkGameDataSynchCheckOk() == false)
|
||||
{
|
||||
label = label + " - waiting to synch:";
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkMap() == false)
|
||||
{
|
||||
label = label + " map";
|
||||
}
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkTile() == false)
|
||||
{
|
||||
label = label + " tile";
|
||||
}
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkTech() == false)
|
||||
{
|
||||
label = label + " techtree";
|
||||
}
|
||||
if(clientInterface->getNetworkGameDataSynchCheckOkFogOfWar() == false)
|
||||
{
|
||||
label = label + " FogOfWar == false";
|
||||
}
|
||||
}
|
||||
else if(clientInterface->getAllowGameDataSynchCheck() == true)
|
||||
{
|
||||
label += " - data synch is ok";
|
||||
}
|
||||
|
||||
labelStatus.setText(label);
|
||||
}
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
buttonConnect.setText(lang.get("Connect"));
|
||||
labelStatus.setText(lang.get("NotConnected"));
|
||||
labelInfo.setText("");
|
||||
}
|
||||
|
||||
//process network messages
|
||||
if(clientInterface->isConnected()){
|
||||
|
||||
if(clientInterface->isConnected())
|
||||
{
|
||||
//update lobby
|
||||
clientInterface->updateLobby();
|
||||
|
||||
|
||||
//call the chat manager
|
||||
chatManager.updateNetwork();
|
||||
|
||||
//console
|
||||
console.update();
|
||||
|
||||
//intro
|
||||
if(clientInterface->getIntroDone()){
|
||||
labelInfo.setText(lang.get("WaitingHost"));
|
||||
if(clientInterface->getIntroDone())
|
||||
{
|
||||
labelInfo.setText(lang.get("WaitingHost"));
|
||||
servers.setString(clientInterface->getServerName(), Ip(labelServerIp.getText()).getString());
|
||||
}
|
||||
|
||||
//launch
|
||||
if(clientInterface->getLaunchGame()){
|
||||
if(clientInterface->getLaunchGame())
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] clientInterface->getLaunchGame() - A\n",__FILE__,__FUNCTION__);
|
||||
|
||||
servers.save(serverFileName);
|
||||
program->setState(new Game(program, clientInterface->getGameSettings()));
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] clientInterface->getLaunchGame() - B\n",__FILE__,__FUNCTION__);
|
||||
|
||||
program->setState(new Game(program, clientInterface->getGameSettings()));
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] clientInterface->getLaunchGame() - C\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText && clientInterface->getLaunchGame()) printf("In [%s::%s] clientInterface->getLaunchGame() - D\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void MenuStateJoinGame::keyDown(char key){
|
||||
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
||||
|
||||
if(!clientInterface->isConnected()){
|
||||
|
||||
if(!clientInterface->isConnected())
|
||||
{
|
||||
if(key==vkBack){
|
||||
string text= labelServerIp.getText();
|
||||
|
||||
|
@ -230,12 +345,18 @@ void MenuStateJoinGame::keyDown(char key){
|
|||
labelServerIp.setText(text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//send key to the chat manager
|
||||
chatManager.keyDown(key);
|
||||
}
|
||||
}
|
||||
|
||||
void MenuStateJoinGame::keyPress(char c){
|
||||
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
||||
|
||||
if(!clientInterface->isConnected()){
|
||||
|
||||
if(!clientInterface->isConnected())
|
||||
{
|
||||
int maxTextSize= 16;
|
||||
|
||||
if(c>='0' && c<='9'){
|
||||
|
@ -258,20 +379,32 @@ void MenuStateJoinGame::keyPress(char c){
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chatManager.keyPress(c);
|
||||
}
|
||||
}
|
||||
|
||||
void MenuStateJoinGame::connectToServer(){
|
||||
void MenuStateJoinGame::connectToServer()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
|
||||
Config& config= Config::getInstance();
|
||||
Ip serverIp(labelServerIp.getText());
|
||||
|
||||
clientInterface->connect(serverIp, GameConstants::serverPort);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] server - [%s]\n",__FILE__,__FUNCTION__,serverIp.getString().c_str());
|
||||
|
||||
labelServerIp.setText(serverIp.getString()+'_');
|
||||
labelInfo.setText("");
|
||||
|
||||
//save server ip
|
||||
config.setString("ServerIp", serverIp.getString());
|
||||
config.save();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2005 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "properties.h"
|
||||
#include "main_menu.h"
|
||||
#include "chat_manager.h"
|
||||
|
||||
using Shared::Util::Properties;
|
||||
|
||||
|
@ -22,7 +23,7 @@ namespace Glest{ namespace Game{
|
|||
class NetworkMessageIntro;
|
||||
|
||||
// ===============================
|
||||
// class MenuStateJoinGame
|
||||
// class MenuStateJoinGame
|
||||
// ===============================
|
||||
|
||||
class MenuStateJoinGame: public MenuState{
|
||||
|
@ -45,6 +46,9 @@ private:
|
|||
int playerIndex;
|
||||
Properties servers;
|
||||
|
||||
Console console;
|
||||
ChatManager chatManager;
|
||||
|
||||
public:
|
||||
MenuStateJoinGame(Program *program, MainMenu *mainMenu, bool connect= false, Ip serverIp= Ip());
|
||||
|
||||
|
@ -52,8 +56,8 @@ public:
|
|||
void mouseMove(int x, int y, const MouseState *mouseState);
|
||||
void render();
|
||||
void update();
|
||||
void keyDown(char key);
|
||||
void keyPress(char c);
|
||||
virtual void keyDown(char key);
|
||||
virtual void keyPress(char c);
|
||||
|
||||
private:
|
||||
void connectToServer();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2005 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2005 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2005 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2005 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -21,6 +21,10 @@
|
|||
#include "lang.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
#include "map.h"
|
||||
#include "config.h"
|
||||
#include "logger.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Shared::Platform;
|
||||
using namespace Shared::Util;
|
||||
|
@ -39,25 +43,56 @@ ClientInterface::ClientInterface(){
|
|||
launchGame= false;
|
||||
introDone= false;
|
||||
playerIndex= -1;
|
||||
|
||||
networkGameDataSynchCheckOkMap = false;
|
||||
networkGameDataSynchCheckOkTile = false;
|
||||
networkGameDataSynchCheckOkTech = false;
|
||||
}
|
||||
|
||||
ClientInterface::~ClientInterface(){
|
||||
ClientInterface::~ClientInterface()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
if(clientSocket != NULL && clientSocket->isConnected() == true)
|
||||
{
|
||||
string sQuitText = getHostName() + " has chosen to leave the game!";
|
||||
sendTextMessage(sQuitText,-1);
|
||||
}
|
||||
|
||||
delete clientSocket;
|
||||
clientSocket = NULL;
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ClientInterface::connect(const Ip &ip, int port){
|
||||
void ClientInterface::connect(const Ip &ip, int port)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
delete clientSocket;
|
||||
|
||||
this->ip = ip;
|
||||
this->port = port;
|
||||
|
||||
clientSocket= new ClientSocket();
|
||||
clientSocket->setBlock(false);
|
||||
clientSocket->connect(ip, port);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END - socket = %d\n",__FILE__,__FUNCTION__,clientSocket->getSocketId());
|
||||
}
|
||||
|
||||
void ClientInterface::reset(){
|
||||
delete clientSocket;
|
||||
clientSocket= NULL;
|
||||
void ClientInterface::reset()
|
||||
{
|
||||
if(getSocket() != NULL)
|
||||
{
|
||||
string sQuitText = getHostName() + " has chosen to leave the game!";
|
||||
sendTextMessage(sQuitText,-1);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientInterface::update(){
|
||||
void ClientInterface::update()
|
||||
{
|
||||
NetworkMessageCommandList networkMessageCommandList;
|
||||
|
||||
//send as many commands as we can
|
||||
|
@ -79,152 +114,363 @@ void ClientInterface::update(){
|
|||
chatTeamIndex= -1;
|
||||
}
|
||||
|
||||
void ClientInterface::updateLobby(){
|
||||
NetworkMessageType networkMessageType= getNextMessageType();
|
||||
|
||||
switch(networkMessageType){
|
||||
case nmtInvalid:
|
||||
break;
|
||||
void ClientInterface::updateLobby()
|
||||
{
|
||||
//clear chat variables
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
case nmtIntro:{
|
||||
NetworkMessageIntro networkMessageIntro;
|
||||
NetworkMessageType networkMessageType = getNextMessageType(true);
|
||||
|
||||
if(receiveMessage(&networkMessageIntro)){
|
||||
|
||||
//check consistency
|
||||
if(Config::getInstance().getBool("NetworkConsistencyChecks")){
|
||||
if(networkMessageIntro.getVersionString()!=getNetworkVersionString()){
|
||||
throw runtime_error("Server and client versions do not match (" + networkMessageIntro.getVersionString() + "). You have to use the same binaries.");
|
||||
}
|
||||
}
|
||||
switch(networkMessageType)
|
||||
{
|
||||
case nmtInvalid:
|
||||
break;
|
||||
|
||||
//send intro message
|
||||
NetworkMessageIntro sendNetworkMessageIntro(getNetworkVersionString(), getHostName(), -1);
|
||||
case nmtIntro:
|
||||
{
|
||||
NetworkMessageIntro networkMessageIntro;
|
||||
|
||||
playerIndex= networkMessageIntro.getPlayerIndex();
|
||||
serverName= networkMessageIntro.getName();
|
||||
sendMessage(&sendNetworkMessageIntro);
|
||||
|
||||
assert(playerIndex>=0 && playerIndex<GameConstants::maxPlayers);
|
||||
introDone= true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if(receiveMessage(&networkMessageIntro))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got NetworkMessageIntro\n",__FILE__,__FUNCTION__);
|
||||
|
||||
case nmtLaunch:{
|
||||
NetworkMessageLaunch networkMessageLaunch;
|
||||
//check consistency
|
||||
if(Config::getInstance().getBool("NetworkConsistencyChecks"))
|
||||
{
|
||||
if(networkMessageIntro.getVersionString()!=getNetworkVersionString())
|
||||
{
|
||||
throw runtime_error("Server and client versions do not match (" + networkMessageIntro.getVersionString() + "). You have to use the same binaries.");
|
||||
}
|
||||
}
|
||||
|
||||
if(receiveMessage(&networkMessageLaunch)){
|
||||
networkMessageLaunch.buildGameSettings(&gameSettings);
|
||||
//send intro message
|
||||
NetworkMessageIntro sendNetworkMessageIntro(getNetworkVersionString(), getHostName(), -1);
|
||||
|
||||
//replace server player by network
|
||||
for(int i= 0; i<gameSettings.getFactionCount(); ++i){
|
||||
|
||||
//replace by network
|
||||
if(gameSettings.getFactionControl(i)==ctHuman){
|
||||
gameSettings.setFactionControl(i, ctNetwork);
|
||||
}
|
||||
playerIndex= networkMessageIntro.getPlayerIndex();
|
||||
serverName= networkMessageIntro.getName();
|
||||
sendMessage(&sendNetworkMessageIntro);
|
||||
|
||||
//set the faction index
|
||||
if(gameSettings.getStartLocationIndex(i)==playerIndex){
|
||||
gameSettings.setThisFactionIndex(i);
|
||||
}
|
||||
}
|
||||
launchGame= true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
assert(playerIndex>=0 && playerIndex<GameConstants::maxPlayers);
|
||||
introDone= true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw runtime_error("Unexpected network message: " + intToStr(networkMessageType));
|
||||
}
|
||||
case nmtSynchNetworkGameData:
|
||||
{
|
||||
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData;
|
||||
|
||||
if(receiveMessage(&networkMessageSynchNetworkGameData))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__);
|
||||
|
||||
// check the checksum's
|
||||
//Checksum checksum;
|
||||
//tileset
|
||||
//string file = "tilesets/" + networkMessageSynchNetworkGameData.getTileset() + "/" + networkMessageSynchNetworkGameData.getTileset() + ".xml";
|
||||
//checksum.addFile(file);
|
||||
// models
|
||||
// sounds
|
||||
// textures
|
||||
//int32 tilesetCRC = checksum.getSum();
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),tilesetCRC);
|
||||
|
||||
//if(tilesetCRC != networkMessageSynchNetworkGameData.getTilesetCRC())
|
||||
//{
|
||||
// if(Socket::enableDebugText) printf("In [%s::%s] tilesetCRC mismatch, local = %d, remote = %d\n",
|
||||
// __FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameData.getTilesetCRC());
|
||||
//}
|
||||
|
||||
int32 tilesetCRC = getFolderTreeContentsCheckSumRecursively("tilesets/" +
|
||||
networkMessageSynchNetworkGameData.getTileset() + "/*", ".xml", NULL);
|
||||
|
||||
this->setNetworkGameDataSynchCheckOkTile((tilesetCRC == networkMessageSynchNetworkGameData.getTilesetCRC()));
|
||||
if(this->getNetworkGameDataSynchCheckOkTile() == false)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] tilesetCRC mismatch, local = %d, remote = %d\n",
|
||||
__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameData.getTilesetCRC());
|
||||
}
|
||||
|
||||
|
||||
//tech, load before map because of resources
|
||||
//checksum = Checksum();
|
||||
//file = "techs/" + networkMessageSynchNetworkGameData.getTech() + "/" + networkMessageSynchNetworkGameData.getTech() + ".xml";
|
||||
//checksum.addFile(file);
|
||||
// factions
|
||||
// resources
|
||||
//int32 techCRC = checksum.getSum();
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),techCRC);
|
||||
|
||||
//if(techCRC != networkMessageSynchNetworkGameData.getTechCRC())
|
||||
//{
|
||||
// if(Socket::enableDebugText) printf("In [%s::%s] techCRC mismatch, local = %d, remote = %d\n",
|
||||
// __FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameData.getTechCRC());
|
||||
//}
|
||||
|
||||
int32 techCRC = getFolderTreeContentsCheckSumRecursively("techs/" +
|
||||
networkMessageSynchNetworkGameData.getTech() + "/*", ".xml", NULL);
|
||||
|
||||
this->setNetworkGameDataSynchCheckOkTech((techCRC == networkMessageSynchNetworkGameData.getTechCRC()));
|
||||
|
||||
if(this->getNetworkGameDataSynchCheckOkTech() == false)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] techCRC mismatch, local = %d, remote = %d\n",
|
||||
__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameData.getTechCRC());
|
||||
}
|
||||
|
||||
//map
|
||||
Checksum checksum;
|
||||
string file = Map::getMapPath(networkMessageSynchNetworkGameData.getMap());
|
||||
checksum.addFile(file);
|
||||
int32 mapCRC = checksum.getSum();
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),mapCRC);
|
||||
|
||||
this->setNetworkGameDataSynchCheckOkMap((mapCRC == networkMessageSynchNetworkGameData.getMapCRC()));
|
||||
|
||||
if(this->getNetworkGameDataSynchCheckOkMap() == false)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] mapCRC mismatch, local = %d, remote = %d\n",
|
||||
__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameData.getMapCRC());
|
||||
}
|
||||
|
||||
|
||||
this->setNetworkGameDataSynchCheckOkFogOfWar((getFogOfWar() == networkMessageSynchNetworkGameData.getFogOfWar()));
|
||||
|
||||
if(this->getNetworkGameDataSynchCheckOkFogOfWar() == false)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] getFogOfWar mismatch, local = %d, remote = %d\n",
|
||||
__FILE__,__FUNCTION__,getFogOfWar(),networkMessageSynchNetworkGameData.getFogOfWar());
|
||||
}
|
||||
|
||||
NetworkMessageSynchNetworkGameDataStatus sendNetworkMessageSynchNetworkGameDataStatus(mapCRC,tilesetCRC,techCRC,getFogOfWar());
|
||||
sendMessage(&sendNetworkMessageSynchNetworkGameDataStatus);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nmtSynchNetworkGameDataFileCRCCheck:
|
||||
{
|
||||
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck;
|
||||
if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck))
|
||||
{
|
||||
/*
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck totalfiles = %d, fileindex = %d, crc = %d, file [%s]\n",
|
||||
__FILE__,__FUNCTION__,networkMessageSynchNetworkGameDataFileCRCCheck.getTotalFileCount(),
|
||||
networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex(),
|
||||
networkMessageSynchNetworkGameDataFileCRCCheck.getFileCRC(),
|
||||
networkMessageSynchNetworkGameDataFileCRCCheck.getFileName().c_str());
|
||||
*/
|
||||
Checksum checksum;
|
||||
string file = networkMessageSynchNetworkGameDataFileCRCCheck.getFileName();
|
||||
checksum.addFile(file);
|
||||
int32 fileCRC = checksum.getSum();
|
||||
|
||||
if(fileCRC != networkMessageSynchNetworkGameDataFileCRCCheck.getFileCRC())
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck localCRC = %d, remoteCRC = %d, file [%s]\n",
|
||||
__FILE__,__FUNCTION__,fileCRC,
|
||||
networkMessageSynchNetworkGameDataFileCRCCheck.getFileCRC(),
|
||||
networkMessageSynchNetworkGameDataFileCRCCheck.getFileName().c_str());
|
||||
|
||||
// Here we initiate a download of missing or mismatched content
|
||||
|
||||
NetworkMessageSynchNetworkGameDataFileGet sendNetworkMessageSynchNetworkGameDataFileGet(networkMessageSynchNetworkGameDataFileCRCCheck.getFileName());
|
||||
sendMessage(&sendNetworkMessageSynchNetworkGameDataFileGet);
|
||||
|
||||
FileTransferInfo fileInfo;
|
||||
fileInfo.hostType = eClient;
|
||||
fileInfo.serverIP = this->ip.getString();
|
||||
fileInfo.serverPort = this->port;
|
||||
fileInfo.fileName = networkMessageSynchNetworkGameDataFileCRCCheck.getFileName();
|
||||
|
||||
FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo);
|
||||
fileXferThread->start();
|
||||
}
|
||||
|
||||
if(networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex() < networkMessageSynchNetworkGameDataFileCRCCheck.getTotalFileCount())
|
||||
{
|
||||
NetworkMessageSynchNetworkGameDataFileCRCCheck sendNetworkMessageSynchNetworkGameDataFileCRCCheck(
|
||||
networkMessageSynchNetworkGameDataFileCRCCheck.getTotalFileCount(),
|
||||
networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex() + 1,
|
||||
0,
|
||||
"");
|
||||
sendMessage(&sendNetworkMessageSynchNetworkGameDataFileCRCCheck);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nmtText:
|
||||
{
|
||||
NetworkMessageText networkMessageText;
|
||||
if(receiveMessage(&networkMessageText))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__);
|
||||
|
||||
chatText = networkMessageText.getText();
|
||||
chatSender = networkMessageText.getSender();
|
||||
chatTeamIndex = networkMessageText.getTeamIndex();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nmtLaunch:
|
||||
{
|
||||
NetworkMessageLaunch networkMessageLaunch;
|
||||
|
||||
if(receiveMessage(&networkMessageLaunch))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got NetworkMessageLaunch\n",__FILE__,__FUNCTION__);
|
||||
|
||||
networkMessageLaunch.buildGameSettings(&gameSettings);
|
||||
|
||||
//replace server player by network
|
||||
for(int i= 0; i<gameSettings.getFactionCount(); ++i)
|
||||
{
|
||||
//replace by network
|
||||
if(gameSettings.getFactionControl(i)==ctHuman)
|
||||
{
|
||||
gameSettings.setFactionControl(i, ctNetwork);
|
||||
}
|
||||
|
||||
//set the faction index
|
||||
if(gameSettings.getStartLocationIndex(i)==playerIndex)
|
||||
{
|
||||
gameSettings.setThisFactionIndex(i);
|
||||
}
|
||||
}
|
||||
launchGame= true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw runtime_error(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType));
|
||||
}
|
||||
}
|
||||
|
||||
void ClientInterface::updateKeyframe(int frameCount){
|
||||
|
||||
void ClientInterface::updateKeyframe(int frameCount)
|
||||
{
|
||||
bool done= false;
|
||||
|
||||
while(!done){
|
||||
while(!done)
|
||||
{
|
||||
//wait for the next message
|
||||
waitForMessage();
|
||||
|
||||
//check we have an expected message
|
||||
NetworkMessageType networkMessageType= getNextMessageType();
|
||||
NetworkMessageType networkMessageType= getNextMessageType(true);
|
||||
|
||||
switch(networkMessageType){
|
||||
case nmtCommandList:{
|
||||
switch(networkMessageType)
|
||||
{
|
||||
case nmtCommandList:
|
||||
{
|
||||
//make sure we read the message
|
||||
NetworkMessageCommandList networkMessageCommandList;
|
||||
while(!receiveMessage(&networkMessageCommandList)){
|
||||
while(!receiveMessage(&networkMessageCommandList))
|
||||
{
|
||||
sleep(waitSleepTime);
|
||||
}
|
||||
|
||||
//check that we are in the right frame
|
||||
if(networkMessageCommandList.getFrameCount()!=frameCount){
|
||||
if(networkMessageCommandList.getFrameCount()!=frameCount)
|
||||
{
|
||||
throw runtime_error("Network synchronization error, frame counts do not match");
|
||||
}
|
||||
|
||||
// give all commands
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i){
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i)
|
||||
{
|
||||
pendingCommands.push_back(*networkMessageCommandList.getCommand(i));
|
||||
}
|
||||
}
|
||||
|
||||
done= true;
|
||||
}
|
||||
break;
|
||||
|
||||
case nmtQuit:{
|
||||
case nmtQuit:
|
||||
{
|
||||
NetworkMessageQuit networkMessageQuit;
|
||||
if(receiveMessage(&networkMessageQuit)){
|
||||
if(receiveMessage(&networkMessageQuit))
|
||||
{
|
||||
quit= true;
|
||||
}
|
||||
done= true;
|
||||
}
|
||||
break;
|
||||
|
||||
case nmtText:{
|
||||
case nmtText:
|
||||
{
|
||||
NetworkMessageText networkMessageText;
|
||||
if(receiveMessage(&networkMessageText)){
|
||||
chatText= networkMessageText.getText();
|
||||
chatSender= networkMessageText.getSender();
|
||||
chatTeamIndex= networkMessageText.getTeamIndex();
|
||||
if(receiveMessage(&networkMessageText))
|
||||
{
|
||||
chatText = networkMessageText.getText();
|
||||
chatSender = networkMessageText.getSender();
|
||||
chatTeamIndex = networkMessageText.getTeamIndex();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case nmtInvalid:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw runtime_error("Unexpected message in client interface: " + intToStr(networkMessageType));
|
||||
throw runtime_error(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected message in client interface: " + intToStr(networkMessageType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientInterface::waitUntilReady(Checksum* checksum){
|
||||
|
||||
NetworkMessageReady networkMessageReady;
|
||||
Chrono chrono;
|
||||
void ClientInterface::waitUntilReady(Checksum* checksum)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
Logger &logger= Logger::getInstance();
|
||||
|
||||
Chrono chrono;
|
||||
chrono.start();
|
||||
|
||||
// FOR TESTING ONLY - delay to see the client count up while waiting
|
||||
//sleep(5000);
|
||||
|
||||
//send ready message
|
||||
NetworkMessageReady networkMessageReady;
|
||||
sendMessage(&networkMessageReady);
|
||||
|
||||
int64 lastMillisCheck = 0;
|
||||
//wait until we get a ready message from the server
|
||||
while(true){
|
||||
|
||||
NetworkMessageType networkMessageType= getNextMessageType();
|
||||
while(true)
|
||||
{
|
||||
NetworkMessageType networkMessageType = getNextMessageType(true);
|
||||
|
||||
if(networkMessageType==nmtReady){
|
||||
if(receiveMessage(&networkMessageReady)){
|
||||
if(networkMessageType == nmtReady)
|
||||
{
|
||||
if(receiveMessage(&networkMessageReady))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(networkMessageType==nmtInvalid){
|
||||
if(chrono.getMillis()>readyWaitTimeout){
|
||||
else if(networkMessageType == nmtInvalid)
|
||||
{
|
||||
if(chrono.getMillis() > readyWaitTimeout)
|
||||
{
|
||||
throw runtime_error("Timeout waiting for server");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(chrono.getMillis() / 1000 > lastMillisCheck)
|
||||
{
|
||||
lastMillisCheck = (chrono.getMillis() / 1000);
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"Waiting for network: %llu seconds elapsed (maximum wait time: %d seconds)",lastMillisCheck,int(readyWaitTimeout / 1000));
|
||||
logger.add(szBuf, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw runtime_error("Unexpected network message: " + intToStr(networkMessageType) );
|
||||
else
|
||||
{
|
||||
throw runtime_error(string(__FILE__) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType) );
|
||||
}
|
||||
|
||||
// sleep a bit
|
||||
|
@ -232,14 +478,18 @@ void ClientInterface::waitUntilReady(Checksum* checksum){
|
|||
}
|
||||
|
||||
//check checksum
|
||||
if(Config::getInstance().getBool("NetworkConsistencyChecks")){
|
||||
if(networkMessageReady.getChecksum()!=checksum->getSum()){
|
||||
if(Config::getInstance().getBool("NetworkConsistencyChecks"))
|
||||
{
|
||||
if(networkMessageReady.getChecksum() != checksum->getSum())
|
||||
{
|
||||
throw runtime_error("Checksum error, you don't have the same data as the server");
|
||||
}
|
||||
}
|
||||
|
||||
//delay the start a bit, so clients have nore room to get messages
|
||||
sleep(GameConstants::networkExtraLatency);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ClientInterface::sendTextMessage(const string &text, int teamIndex){
|
||||
|
@ -251,18 +501,20 @@ string ClientInterface::getNetworkStatus() const{
|
|||
return Lang::getInstance().get("Server") + ": " + serverName;
|
||||
}
|
||||
|
||||
void ClientInterface::waitForMessage(){
|
||||
void ClientInterface::waitForMessage()
|
||||
{
|
||||
Chrono chrono;
|
||||
|
||||
chrono.start();
|
||||
|
||||
while(getNextMessageType()==nmtInvalid){
|
||||
|
||||
if(!isConnected()){
|
||||
while(getNextMessageType(true) == nmtInvalid)
|
||||
{
|
||||
if(!isConnected())
|
||||
{
|
||||
throw runtime_error("Disconnected");
|
||||
}
|
||||
|
||||
if(chrono.getMillis()>messageWaitTimeout){
|
||||
if(chrono.getMillis()>messageWaitTimeout)
|
||||
{
|
||||
throw runtime_error("Timeout waiting for message");
|
||||
}
|
||||
|
||||
|
@ -270,4 +522,31 @@ void ClientInterface::waitForMessage(){
|
|||
}
|
||||
}
|
||||
|
||||
void ClientInterface::quitGame(bool userManuallyQuit)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
if(clientSocket != NULL && userManuallyQuit == true)
|
||||
{
|
||||
string sQuitText = getHostName() + " has chosen to leave the game!";
|
||||
sendTextMessage(sQuitText,-1);
|
||||
close();
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ClientInterface::close()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
delete clientSocket;
|
||||
clientSocket= NULL;
|
||||
}
|
||||
|
||||
bool ClientInterface::getFogOfWar()
|
||||
{
|
||||
return Config::getInstance().getBool("FogOfWar");
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "network_interface.h"
|
||||
#include "game_settings.h"
|
||||
//#include "game_settings.h"
|
||||
|
||||
#include "socket.h"
|
||||
|
||||
|
@ -36,18 +36,22 @@ private:
|
|||
|
||||
private:
|
||||
ClientSocket *clientSocket;
|
||||
GameSettings gameSettings;
|
||||
//GameSettings gameSettings;
|
||||
string serverName;
|
||||
bool introDone;
|
||||
bool launchGame;
|
||||
int playerIndex;
|
||||
|
||||
Ip ip;
|
||||
int port;
|
||||
|
||||
public:
|
||||
ClientInterface();
|
||||
virtual ~ClientInterface();
|
||||
|
||||
virtual Socket* getSocket() {return clientSocket;}
|
||||
virtual const Socket* getSocket() const {return clientSocket;}
|
||||
virtual void close();
|
||||
|
||||
//message processing
|
||||
virtual void update();
|
||||
|
@ -57,7 +61,7 @@ public:
|
|||
|
||||
// message sending
|
||||
virtual void sendTextMessage(const string &text, int teamIndex);
|
||||
virtual void quitGame(){}
|
||||
virtual void quitGame(bool userManuallyQuit);
|
||||
|
||||
//misc
|
||||
virtual string getNetworkStatus() const;
|
||||
|
@ -67,10 +71,11 @@ public:
|
|||
bool getLaunchGame() const {return launchGame;}
|
||||
bool getIntroDone() const {return introDone;}
|
||||
int getPlayerIndex() const {return playerIndex;}
|
||||
const GameSettings *getGameSettings() {return &gameSettings;}
|
||||
//const GameSettings *getGameSettings() {return &gameSettings;}
|
||||
|
||||
void connect(const Ip &ip, int port);
|
||||
void reset();
|
||||
virtual bool getFogOfWar();
|
||||
|
||||
private:
|
||||
void waitForMessage();
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -20,8 +20,12 @@
|
|||
#include "network_message.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
#include "platform_util.h"
|
||||
#include "map.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Shared::Util;
|
||||
//using namespace Shared::Platform;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
|
@ -29,43 +33,108 @@ namespace Glest{ namespace Game{
|
|||
// class ClientConnection
|
||||
// =====================================================
|
||||
|
||||
ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex){
|
||||
ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex)
|
||||
{
|
||||
this->serverInterface= serverInterface;
|
||||
this->playerIndex= playerIndex;
|
||||
socket= NULL;
|
||||
ready= false;
|
||||
|
||||
networkGameDataSynchCheckOkMap = false;
|
||||
networkGameDataSynchCheckOkTile = false;
|
||||
networkGameDataSynchCheckOkTech = false;
|
||||
networkGameDataSynchCheckOkFogOfWar = false;
|
||||
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
}
|
||||
|
||||
ConnectionSlot::~ConnectionSlot(){
|
||||
ConnectionSlot::~ConnectionSlot()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
close();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ConnectionSlot::update(){
|
||||
if(socket==NULL){
|
||||
socket= serverInterface->getServerSocket()->accept();
|
||||
void ConnectionSlot::update()
|
||||
{
|
||||
update(true);
|
||||
}
|
||||
|
||||
//send intro message when connected
|
||||
if(socket!=NULL){
|
||||
NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), socket->getHostName(), playerIndex);
|
||||
sendMessage(&networkMessageIntro);
|
||||
}
|
||||
void ConnectionSlot::update(bool checkForNewClients)
|
||||
{
|
||||
if(socket == NULL)
|
||||
{
|
||||
if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false;
|
||||
if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false;
|
||||
if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false;
|
||||
if(networkGameDataSynchCheckOkFogOfWar) networkGameDataSynchCheckOkFogOfWar = false;
|
||||
|
||||
// Is the listener socket ready to be read?
|
||||
//if(serverInterface->getServerSocket()->isReadable() == true)
|
||||
if(checkForNewClients == true)
|
||||
{
|
||||
socket = serverInterface->getServerSocket()->accept();
|
||||
|
||||
//send intro message when connected
|
||||
if(socket != NULL)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] accepted new client connection\n",__FILE__,__FUNCTION__);
|
||||
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
NetworkMessageIntro networkMessageIntro(getNetworkVersionString(), socket->getHostName(), playerIndex);
|
||||
sendMessage(&networkMessageIntro);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(socket->isConnected()){
|
||||
else
|
||||
{
|
||||
if(socket->isConnected())
|
||||
{
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
NetworkMessageType networkMessageType= getNextMessageType();
|
||||
|
||||
//process incoming commands
|
||||
switch(networkMessageType){
|
||||
|
||||
|
||||
case nmtInvalid:
|
||||
case nmtText:
|
||||
break;
|
||||
|
||||
case nmtText:
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtText\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageText networkMessageText;
|
||||
if(receiveMessage(&networkMessageText))
|
||||
{
|
||||
chatText = networkMessageText.getText();
|
||||
chatSender = networkMessageText.getSender();
|
||||
chatTeamIndex = networkMessageText.getTeamIndex();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] chatText [%s] chatSender [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,chatText.c_str(),chatSender.c_str(),chatTeamIndex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//command list
|
||||
case nmtCommandList:{
|
||||
case nmtCommandList: {
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtCommandList\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageCommandList networkMessageCommandList;
|
||||
if(receiveMessage(&networkMessageCommandList)){
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i){
|
||||
if(receiveMessage(&networkMessageCommandList))
|
||||
{
|
||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i)
|
||||
{
|
||||
serverInterface->requestCommand(networkMessageCommandList.getCommand(i));
|
||||
}
|
||||
}
|
||||
|
@ -73,10 +142,143 @@ void ConnectionSlot::update(){
|
|||
break;
|
||||
|
||||
//process intro messages
|
||||
case nmtIntro:{
|
||||
case nmtIntro:
|
||||
{
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtIntro\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageIntro networkMessageIntro;
|
||||
if(receiveMessage(&networkMessageIntro)){
|
||||
if(receiveMessage(&networkMessageIntro))
|
||||
{
|
||||
name= networkMessageIntro.getName();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got name [%s]\n",__FILE__,__FUNCTION__,name.c_str());
|
||||
|
||||
if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings());
|
||||
sendMessage(&networkMessageSynchNetworkGameData);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//process datasynch messages
|
||||
case nmtSynchNetworkGameDataStatus:
|
||||
{
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] got nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__);
|
||||
|
||||
NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus;
|
||||
if(receiveMessage(&networkMessageSynchNetworkGameDataStatus))
|
||||
{
|
||||
receivedNetworkGameStatus = true;
|
||||
|
||||
int32 tilesetCRC = getFolderTreeContentsCheckSumRecursively("tilesets/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", NULL);
|
||||
int32 techCRC = getFolderTreeContentsCheckSumRecursively("techs/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL);
|
||||
Checksum checksum;
|
||||
string file = Map::getMapPath(serverInterface->getGameSettings()->getMap());
|
||||
checksum.addFile(file);
|
||||
int32 mapCRC = checksum.getSum();
|
||||
|
||||
networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC);
|
||||
networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC);
|
||||
networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC);
|
||||
networkGameDataSynchCheckOkFogOfWar = (networkMessageSynchNetworkGameDataStatus.getFogOfWar() == serverInterface->getFogOfWar() == true);
|
||||
|
||||
// For testing
|
||||
//techCRC++;
|
||||
|
||||
if( networkGameDataSynchCheckOkMap == true &&
|
||||
networkGameDataSynchCheckOkTile == true &&
|
||||
networkGameDataSynchCheckOkTech == true &&
|
||||
networkGameDataSynchCheckOkFogOfWar == true)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC());
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC());
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC());
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] serverInterface->getFogOfWar() = %d, remote = %d\n",__FILE__,__FUNCTION__,serverInterface->getFogOfWar(),networkMessageSynchNetworkGameDataStatus.getFogOfWar());
|
||||
|
||||
if(allowDownloadDataSynch == true)
|
||||
{
|
||||
// Now get all filenames with their CRC values and send to the client
|
||||
vctFileList.clear();
|
||||
|
||||
if(networkGameDataSynchCheckOkTile == false)
|
||||
{
|
||||
if(tilesetCRC == 0)
|
||||
{
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively("tilesets/" + serverInterface->getGameSettings()->getTileset() + "/*", "", &vctFileList);
|
||||
}
|
||||
else
|
||||
{
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively("tilesets/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
|
||||
}
|
||||
}
|
||||
if(networkGameDataSynchCheckOkTech == false)
|
||||
{
|
||||
if(techCRC == 0)
|
||||
{
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively("techs/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
|
||||
}
|
||||
else
|
||||
{
|
||||
vctFileList = getFolderTreeContentsCheckSumListRecursively("techs/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
|
||||
}
|
||||
}
|
||||
if(networkGameDataSynchCheckOkMap == false)
|
||||
{
|
||||
vctFileList.push_back(std::pair<string,int32>(Map::getMapPath(serverInterface->getGameSettings()->getMap()),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:
|
||||
{
|
||||
|
||||
if(Socket::enableDebugText) printf("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:
|
||||
{
|
||||
|
||||
if(Socket::enableDebugText) printf("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 = GameConstants::serverPort;
|
||||
fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName();
|
||||
|
||||
FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo);
|
||||
fileXferThread->start();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -85,15 +287,38 @@ void ConnectionSlot::update(){
|
|||
throw runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType));
|
||||
}
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] calling close...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionSlot::close(){
|
||||
void ConnectionSlot::close()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
delete socket;
|
||||
socket= NULL;
|
||||
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
bool ConnectionSlot::getFogOfWar()
|
||||
{
|
||||
return networkGameDataSynchCheckOkFogOfWar;
|
||||
}
|
||||
|
||||
bool ConnectionSlot::hasValidSocketId()
|
||||
{
|
||||
bool result = (socket != NULL && socket->getSocketId() > 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -37,23 +37,30 @@ private:
|
|||
int playerIndex;
|
||||
string name;
|
||||
bool ready;
|
||||
vector<std::pair<string,int32> > vctFileList;
|
||||
bool receivedNetworkGameStatus;
|
||||
|
||||
public:
|
||||
ConnectionSlot(ServerInterface* serverInterface, int playerIndex);
|
||||
~ConnectionSlot();
|
||||
|
||||
void update(bool checkForNewClients);
|
||||
virtual void update();
|
||||
|
||||
void setReady() {ready= true;}
|
||||
const string &getName() const {return name;}
|
||||
bool isReady() const {return ready;}
|
||||
|
||||
protected:
|
||||
virtual Socket* getSocket() {return socket;}
|
||||
virtual Socket* getSocket() const {return socket;}
|
||||
|
||||
private:
|
||||
void close();
|
||||
virtual void close();
|
||||
virtual bool getFogOfWar();
|
||||
|
||||
bool getReceivedNetworkGameStatus() { return receivedNetworkGameStatus; }
|
||||
void setReceivedNetworkGameStatus(bool value) { receivedNetworkGameStatus = value; }
|
||||
|
||||
bool hasValidSocketId();
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
|||
#include "platform_util.h"
|
||||
|
||||
#include "leak_dumper.h"
|
||||
#include <fstream>
|
||||
|
||||
using namespace Shared::Platform;
|
||||
using namespace Shared::Util;
|
||||
|
@ -32,6 +33,9 @@ namespace Glest{ namespace Game{
|
|||
|
||||
const int NetworkInterface::readyWaitTimeout= 60000; //1 minute
|
||||
|
||||
bool NetworkInterface::allowGameDataSynchCheck = false;
|
||||
bool NetworkInterface::allowDownloadDataSynch = false;
|
||||
|
||||
|
||||
void NetworkInterface::sendMessage(const NetworkMessage* networkMessage){
|
||||
Socket* socket= getSocket();
|
||||
|
@ -39,31 +43,52 @@ void NetworkInterface::sendMessage(const NetworkMessage* networkMessage){
|
|||
networkMessage->send(socket);
|
||||
}
|
||||
|
||||
NetworkMessageType NetworkInterface::getNextMessageType(){
|
||||
NetworkMessageType NetworkInterface::getNextMessageType(bool checkHasDataFirst)
|
||||
{
|
||||
Socket* socket= getSocket();
|
||||
int8 messageType= nmtInvalid;
|
||||
|
||||
//peek message type
|
||||
if(socket->getDataToRead()>=sizeof(messageType)){
|
||||
socket->peek(&messageType, sizeof(messageType));
|
||||
}
|
||||
if(checkHasDataFirst == false ||
|
||||
(checkHasDataFirst == true &&
|
||||
socket != NULL &&
|
||||
socket->hasDataToRead() == true))
|
||||
{
|
||||
//peek message type
|
||||
int dataSize = socket->getDataToRead();
|
||||
if(dataSize >= sizeof(messageType)){
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] socket->getDataToRead() dataSize = %d\n",__FILE__,__FUNCTION__,dataSize);
|
||||
|
||||
//sanity check new message type
|
||||
if(messageType<0 || messageType>=nmtCount){
|
||||
throw runtime_error("Invalid message type: " + intToStr(messageType));
|
||||
}
|
||||
int iPeek = socket->peek(&messageType, sizeof(messageType));
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] socket->getDataToRead() iPeek = %d, messageType = %d\n",__FILE__,__FUNCTION__,iPeek,messageType);
|
||||
}
|
||||
|
||||
//sanity check new message type
|
||||
if(messageType<0 || messageType>=nmtCount){
|
||||
throw runtime_error("Invalid message type: " + intToStr(messageType));
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<NetworkMessageType>(messageType);
|
||||
}
|
||||
|
||||
bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage){
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s]\n",__FILE__,__FUNCTION__);
|
||||
|
||||
Socket* socket= getSocket();
|
||||
|
||||
return networkMessage->receive(socket);
|
||||
}
|
||||
|
||||
bool NetworkInterface::isConnected(){
|
||||
return getSocket()!=NULL && getSocket()->isConnected();
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
bool result = (getSocket()!=NULL && getSocket()->isConnected());
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
|
@ -74,4 +99,181 @@ GameNetworkInterface::GameNetworkInterface(){
|
|||
quit= false;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class FileTransferSocketThread
|
||||
// =====================================================
|
||||
|
||||
const int32 SEND_FILE = 0x20;
|
||||
const int32 ACK = 0x47;
|
||||
|
||||
FileTransferSocketThread::FileTransferSocketThread(FileTransferInfo fileInfo)
|
||||
{
|
||||
this->info = fileInfo;
|
||||
this->info.serverPort += 100;
|
||||
}
|
||||
|
||||
void FileTransferSocketThread::execute()
|
||||
{
|
||||
if(info.hostType == eServer)
|
||||
{
|
||||
ServerSocket serverSocket;
|
||||
//serverSocket.setBlock(false);
|
||||
serverSocket.bind(this->info.serverPort);
|
||||
serverSocket.listen(1);
|
||||
Socket *clientSocket = serverSocket.accept();
|
||||
|
||||
char data[513]="";
|
||||
memset(data, 0, 256);
|
||||
|
||||
clientSocket->receive(data,256);
|
||||
if(*data == SEND_FILE)
|
||||
{
|
||||
FileInfo file;
|
||||
|
||||
memcpy(&file, data+1, sizeof(file));
|
||||
|
||||
*data=ACK;
|
||||
clientSocket->send(data,256);
|
||||
|
||||
Checksum checksum;
|
||||
checksum.addFile(file.fileName);
|
||||
file.filecrc = checksum.getSum();
|
||||
|
||||
ifstream infile(file.fileName.c_str(), ios::in | ios::binary | ios::ate);
|
||||
if(infile.is_open() == true)
|
||||
{
|
||||
file.filesize = infile.tellg();
|
||||
infile.seekg (0, ios::beg);
|
||||
|
||||
memset(data, 0, 256);
|
||||
*data=SEND_FILE;
|
||||
memcpy(data+1,&file,sizeof(file));
|
||||
|
||||
clientSocket->send(data,256);
|
||||
clientSocket->receive(data,256);
|
||||
if(*data != ACK)
|
||||
;//transfer error
|
||||
|
||||
int remain=file.filesize % 512 ;
|
||||
int packs=(file.filesize-remain)/512;
|
||||
|
||||
while(packs--)
|
||||
{
|
||||
infile.read(data,512);
|
||||
//if(!ReadFile(file,data,512,&read,NULL))
|
||||
// ; //read error
|
||||
//if(written!=pack)
|
||||
// ; //read error
|
||||
clientSocket->send(data,512);
|
||||
clientSocket->receive(data,256);
|
||||
if(*data!=ACK)
|
||||
;//transfer error
|
||||
}
|
||||
|
||||
infile.read(data,remain);
|
||||
//if(!ReadFile(file,data,remain,&read,NULL))
|
||||
// ; //read error
|
||||
//if(written!=pack)
|
||||
// ; //read error
|
||||
|
||||
clientSocket->send(data,remain);
|
||||
clientSocket->receive(data,256);
|
||||
if(*data!=ACK)
|
||||
;//transfer error
|
||||
|
||||
infile.close();
|
||||
}
|
||||
}
|
||||
|
||||
delete clientSocket;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ip ip(this->info.serverIP);
|
||||
ClientSocket clientSocket;
|
||||
//clientSocket.setBlock(false);
|
||||
clientSocket.connect(this->info.serverIP, this->info.serverPort);
|
||||
|
||||
if(clientSocket.isConnected() == true)
|
||||
{
|
||||
FileInfo file;
|
||||
file.fileName = this->info.fileName;
|
||||
//file.filesize =
|
||||
//file.filecrc = this->info.
|
||||
|
||||
string path = extractDirectoryPathFromFile(file.fileName);
|
||||
createDirectoryPaths(path);
|
||||
ofstream outFile(file.fileName.c_str(), ios_base::binary | ios_base::out);
|
||||
if(outFile.is_open() == true)
|
||||
{
|
||||
char data[513]="";
|
||||
memset(data, 0, 256);
|
||||
*data=SEND_FILE;
|
||||
memcpy(data+1,&file,sizeof(file));
|
||||
|
||||
clientSocket.send(data,256);
|
||||
clientSocket.receive(data,256);
|
||||
if(*data!=ACK)
|
||||
;//transfer error
|
||||
|
||||
clientSocket.receive(data,256);
|
||||
if(*data == SEND_FILE)
|
||||
{
|
||||
memcpy(&file, data+1, sizeof(file));
|
||||
*data=ACK;
|
||||
clientSocket.send(data,256);
|
||||
|
||||
int remain = file.filesize % 512 ;
|
||||
int packs = (file.filesize-remain) / 512;
|
||||
|
||||
while(packs--)
|
||||
{
|
||||
clientSocket.receive(data,512);
|
||||
|
||||
outFile.write(data, 512);
|
||||
if(outFile.bad())
|
||||
{
|
||||
int ii = 0;
|
||||
}
|
||||
//if(!WriteFile(file,data,512,&written,NULL))
|
||||
// ; //write error
|
||||
//if(written != pack)
|
||||
// ; //write error
|
||||
*data=ACK;
|
||||
clientSocket.send(data,256);
|
||||
}
|
||||
clientSocket.receive(data,remain);
|
||||
|
||||
outFile.write(data, remain);
|
||||
if(outFile.bad())
|
||||
{
|
||||
int ii = 0;
|
||||
}
|
||||
|
||||
//if(!WriteFile(file,data,remain,&written,NULL))
|
||||
// ; //write error
|
||||
//if(written!=pack)
|
||||
// ; //write error
|
||||
*data=ACK;
|
||||
clientSocket.send(data,256);
|
||||
|
||||
Checksum checksum;
|
||||
checksum.addFile(file.fileName);
|
||||
int32 crc = checksum.getSum();
|
||||
if(file.filecrc != crc)
|
||||
{
|
||||
int ii = 0;
|
||||
}
|
||||
|
||||
//if(calc_crc(file)!=info.crc)
|
||||
// ; //transfeer error
|
||||
}
|
||||
|
||||
outFile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -19,40 +19,88 @@
|
|||
#include "network_message.h"
|
||||
#include "network_types.h"
|
||||
|
||||
#include "game_settings.h"
|
||||
|
||||
#include "thread.h"
|
||||
#include "types.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using Shared::Util::Checksum;
|
||||
using namespace Shared::Util;
|
||||
using namespace Shared::Platform;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
//class GameSettings;
|
||||
|
||||
// =====================================================
|
||||
// class NetworkInterface
|
||||
// =====================================================
|
||||
|
||||
class NetworkInterface{
|
||||
class NetworkInterface {
|
||||
|
||||
protected:
|
||||
static bool allowGameDataSynchCheck;
|
||||
static bool allowDownloadDataSynch;
|
||||
bool networkGameDataSynchCheckOkMap;
|
||||
bool networkGameDataSynchCheckOkTile;
|
||||
bool networkGameDataSynchCheckOkTech;
|
||||
bool networkGameDataSynchCheckOkFogOfWar;
|
||||
|
||||
string chatText;
|
||||
string chatSender;
|
||||
int chatTeamIndex;
|
||||
|
||||
public:
|
||||
static const int readyWaitTimeout;
|
||||
GameSettings gameSettings;
|
||||
|
||||
public:
|
||||
virtual ~NetworkInterface(){}
|
||||
|
||||
virtual Socket* getSocket()= 0;
|
||||
virtual const Socket* getSocket() const= 0;
|
||||
virtual void close()= 0;
|
||||
|
||||
string getIp() const {return getSocket()->getIp();}
|
||||
string getHostName() const {return getSocket()->getHostName();}
|
||||
|
||||
void sendMessage(const NetworkMessage* networkMessage);
|
||||
NetworkMessageType getNextMessageType();
|
||||
NetworkMessageType getNextMessageType(bool checkHasDataFirst = false);
|
||||
bool receiveMessage(NetworkMessage* networkMessage);
|
||||
|
||||
bool isConnected();
|
||||
|
||||
//virtual void setGameSettings(GameSettings *serverGameSettings) { gameSettings = *serverGameSettings; }
|
||||
const virtual GameSettings * getGameSettings() { return &gameSettings; }
|
||||
|
||||
virtual void setAllowDownloadDataSynch(bool value) { allowDownloadDataSynch = value; }
|
||||
virtual bool getAllowDownloadDataSynch() { return allowDownloadDataSynch; }
|
||||
|
||||
virtual void setAllowGameDataSynchCheck(bool value) { allowGameDataSynchCheck = value; }
|
||||
virtual bool getAllowGameDataSynchCheck() { return allowGameDataSynchCheck; }
|
||||
|
||||
virtual bool getNetworkGameDataSynchCheckOk() { return (networkGameDataSynchCheckOkMap && networkGameDataSynchCheckOkTile && networkGameDataSynchCheckOkTech && networkGameDataSynchCheckOkFogOfWar); }
|
||||
virtual void setNetworkGameDataSynchCheckOkMap(bool value) { networkGameDataSynchCheckOkMap = value; }
|
||||
virtual void setNetworkGameDataSynchCheckOkTile(bool value) { networkGameDataSynchCheckOkTile = value; }
|
||||
virtual void setNetworkGameDataSynchCheckOkTech(bool value) { networkGameDataSynchCheckOkTech = value; }
|
||||
virtual bool getNetworkGameDataSynchCheckOkMap() { return networkGameDataSynchCheckOkMap; }
|
||||
virtual bool getNetworkGameDataSynchCheckOkTile() { return networkGameDataSynchCheckOkTile; }
|
||||
virtual bool getNetworkGameDataSynchCheckOkTech() { return networkGameDataSynchCheckOkTech; }
|
||||
virtual bool getFogOfWar()=0;
|
||||
virtual bool getNetworkGameDataSynchCheckOkFogOfWar() { return networkGameDataSynchCheckOkFogOfWar; }
|
||||
virtual void setNetworkGameDataSynchCheckOkFogOfWar(bool value) { networkGameDataSynchCheckOkFogOfWar = value; }
|
||||
|
||||
const string getChatText() const {return chatText;}
|
||||
const string getChatSender() const {return chatSender;}
|
||||
int getChatTeamIndex() const {return chatTeamIndex;}
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class GameNetworkInterface
|
||||
//
|
||||
// Adds functions common to servers and clients
|
||||
//
|
||||
// Adds functions common to servers and clients
|
||||
// but not connection slots
|
||||
// =====================================================
|
||||
|
||||
|
@ -64,9 +112,6 @@ protected:
|
|||
Commands requestedCommands; //commands requested by the user
|
||||
Commands pendingCommands; //commands ready to be given
|
||||
bool quit;
|
||||
string chatText;
|
||||
string chatSender;
|
||||
int chatTeamIndex;
|
||||
|
||||
public:
|
||||
GameNetworkInterface();
|
||||
|
@ -79,7 +124,7 @@ public:
|
|||
|
||||
//message sending
|
||||
virtual void sendTextMessage(const string &text, int teamIndex)= 0;
|
||||
virtual void quitGame()=0;
|
||||
virtual void quitGame(bool userManuallyQuit)=0;
|
||||
|
||||
//misc
|
||||
virtual string getNetworkStatus() const= 0;
|
||||
|
@ -90,11 +135,77 @@ public:
|
|||
const NetworkCommand* getPendingCommand(int i) const {return &pendingCommands[i];}
|
||||
void clearPendingCommands() {pendingCommands.clear();}
|
||||
bool getQuit() const {return quit;}
|
||||
const string getChatText() const {return chatText;}
|
||||
const string getChatSender() const {return chatSender;}
|
||||
int getChatTeamIndex() const {return chatTeamIndex;}
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class FileTransferSocketThread
|
||||
// =====================================================
|
||||
|
||||
enum FileTransferHostType
|
||||
{
|
||||
eClient,
|
||||
eServer
|
||||
};
|
||||
|
||||
enum FileTransferOperationType
|
||||
{
|
||||
eSend,
|
||||
eReceive
|
||||
};
|
||||
|
||||
class FileTransferInfo
|
||||
{
|
||||
private:
|
||||
|
||||
void CopyAll(const FileTransferInfo &obj)
|
||||
{
|
||||
hostType = obj.hostType;
|
||||
serverIP = obj.serverIP;
|
||||
serverPort = obj.serverPort;
|
||||
opType = obj.opType;
|
||||
fileName = obj.fileName;
|
||||
}
|
||||
|
||||
public:
|
||||
FileTransferInfo()
|
||||
{
|
||||
}
|
||||
FileTransferInfo(const FileTransferInfo &obj)
|
||||
{
|
||||
CopyAll(obj);
|
||||
}
|
||||
FileTransferInfo &operator=(const FileTransferInfo &obj)
|
||||
{
|
||||
CopyAll(obj);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileTransferHostType hostType;
|
||||
string serverIP;
|
||||
int32 serverPort;
|
||||
FileTransferOperationType opType;
|
||||
string fileName;
|
||||
};
|
||||
|
||||
class FileInfo
|
||||
{
|
||||
public:
|
||||
string fileName;
|
||||
int64 filesize;
|
||||
int32 filecrc;
|
||||
};
|
||||
|
||||
class FileTransferSocketThread : public Thread
|
||||
{
|
||||
private:
|
||||
FileTransferInfo info;
|
||||
|
||||
public:
|
||||
FileTransferSocketThread(FileTransferInfo fileInfo);
|
||||
virtual void execute();
|
||||
};
|
||||
|
||||
|
||||
}}//end namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -20,6 +20,11 @@
|
|||
|
||||
#include "leak_dumper.h"
|
||||
|
||||
#include "checksum.h"
|
||||
#include "map.h"
|
||||
#include "platform_util.h"
|
||||
#include "config.h"
|
||||
|
||||
using namespace Shared::Platform;
|
||||
using namespace Shared::Util;
|
||||
using namespace std;
|
||||
|
@ -30,19 +35,48 @@ namespace Glest{ namespace Game{
|
|||
// class NetworkMessage
|
||||
// =====================================================
|
||||
|
||||
bool NetworkMessage::receive(Socket* socket, void* data, int dataSize){
|
||||
if(socket->getDataToRead()>=dataSize){
|
||||
if(socket->receive(data, dataSize)!=dataSize){
|
||||
throw runtime_error("Error receiving NetworkMessage");
|
||||
bool NetworkMessage::receive(Socket* socket, void* data, int dataSize)
|
||||
{
|
||||
int ipeekdatalen = socket->getDataToRead();
|
||||
|
||||
if(ipeekdatalen >= dataSize)
|
||||
{
|
||||
if(socket->receive(data, dataSize)!=dataSize)
|
||||
{
|
||||
if(socket != NULL && socket->getSocketId() > 0)
|
||||
{
|
||||
throw runtime_error("Error receiving NetworkMessage");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] socket has been disconnected\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] dataSize = %d\n",__FILE__,__FUNCTION__,dataSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] socket->getDataToRead() returned %d\n",__FILE__,__FUNCTION__,ipeekdatalen);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkMessage::send(Socket* socket, const void* data, int dataSize) const{
|
||||
if(socket->send(data, dataSize)!=dataSize){
|
||||
throw runtime_error("Error sending NetworkMessage");
|
||||
void NetworkMessage::send(Socket* socket, const void* data, int dataSize) const
|
||||
{
|
||||
if(socket->send(data, dataSize)!=dataSize)
|
||||
{
|
||||
if(socket != NULL && socket->getSocketId() > 0)
|
||||
{
|
||||
throw runtime_error("Error sending NetworkMessage");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] socket has been disconnected\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,12 +85,12 @@ void NetworkMessage::send(Socket* socket, const void* data, int dataSize) const{
|
|||
// =====================================================
|
||||
|
||||
NetworkMessageIntro::NetworkMessageIntro(){
|
||||
data.messageType= -1;
|
||||
data.messageType= -1;
|
||||
data.playerIndex= -1;
|
||||
}
|
||||
|
||||
NetworkMessageIntro::NetworkMessageIntro(const string &versionString, const string &name, int playerIndex){
|
||||
data.messageType=nmtIntro;
|
||||
data.messageType=nmtIntro;
|
||||
data.versionString= versionString;
|
||||
data.name= name;
|
||||
data.playerIndex= static_cast<int16>(playerIndex);
|
||||
|
@ -76,11 +110,11 @@ void NetworkMessageIntro::send(Socket* socket) const{
|
|||
// =====================================================
|
||||
|
||||
NetworkMessageReady::NetworkMessageReady(){
|
||||
data.messageType= nmtReady;
|
||||
data.messageType= nmtReady;
|
||||
}
|
||||
|
||||
NetworkMessageReady::NetworkMessageReady(int32 checksum){
|
||||
data.messageType= nmtReady;
|
||||
data.messageType= nmtReady;
|
||||
data.checksum= checksum;
|
||||
}
|
||||
|
||||
|
@ -98,7 +132,7 @@ void NetworkMessageReady::send(Socket* socket) const{
|
|||
// =====================================================
|
||||
|
||||
NetworkMessageLaunch::NetworkMessageLaunch(){
|
||||
data.messageType=-1;
|
||||
data.messageType=-1;
|
||||
}
|
||||
|
||||
NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings){
|
||||
|
@ -170,12 +204,23 @@ bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand)
|
|||
}
|
||||
|
||||
bool NetworkMessageCommandList::receive(Socket* socket){
|
||||
return NetworkMessage::receive(socket, &data, sizeof(data));
|
||||
//return NetworkMessage::receive(socket, &data, sizeof(data));
|
||||
|
||||
// read type, commandCount & frame num first.
|
||||
if (!NetworkMessage::receive(socket, &data, networkPacketMsgTypeSize)) {
|
||||
return false;
|
||||
}
|
||||
// read data.commandCount commands.
|
||||
if (data.commandCount) {
|
||||
return NetworkMessage::receive(socket, &data.commands, sizeof(NetworkCommand) * data.commandCount);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetworkMessageCommandList::send(Socket* socket) const{
|
||||
assert(data.messageType==nmtCommandList);
|
||||
NetworkMessage::send(socket, &data, sizeof(data));
|
||||
//NetworkMessage::send(socket, &data, sizeof(data));
|
||||
NetworkMessage::send(socket, &data, networkPacketMsgTypeSize + sizeof(NetworkCommand) * data.commandCount);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
|
@ -183,7 +228,7 @@ void NetworkMessageCommandList::send(Socket* socket) const{
|
|||
// =====================================================
|
||||
|
||||
NetworkMessageText::NetworkMessageText(const string &text, const string &sender, int teamIndex){
|
||||
data.messageType= nmtText;
|
||||
data.messageType= nmtText;
|
||||
data.text= text;
|
||||
data.sender= sender;
|
||||
data.teamIndex= teamIndex;
|
||||
|
@ -203,7 +248,7 @@ void NetworkMessageText::send(Socket* socket) const{
|
|||
// =====================================================
|
||||
|
||||
NetworkMessageQuit::NetworkMessageQuit(){
|
||||
data.messageType= nmtQuit;
|
||||
data.messageType= nmtQuit;
|
||||
}
|
||||
|
||||
bool NetworkMessageQuit::receive(Socket* socket){
|
||||
|
@ -215,4 +260,133 @@ void NetworkMessageQuit::send(Socket* socket) const{
|
|||
NetworkMessage::send(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameData
|
||||
// =====================================================
|
||||
|
||||
NetworkMessageSynchNetworkGameData::NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings)
|
||||
{
|
||||
data.messageType= nmtSynchNetworkGameData;
|
||||
|
||||
data.map = gameSettings->getMap();
|
||||
data.tileset = gameSettings->getTileset();
|
||||
data.tech = gameSettings->getTech();
|
||||
|
||||
//Checksum checksum;
|
||||
//tileset
|
||||
//string file = "tilesets/" + gameSettings->getTileset() + "/" + gameSettings->getTileset() + ".xml";
|
||||
//checksum.addFile(file);
|
||||
// models
|
||||
// sounds
|
||||
// textures
|
||||
//data.tilesetCRC = checksum.getSum();
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),data.tilesetCRC);
|
||||
data.tilesetCRC = getFolderTreeContentsCheckSumRecursively("tilesets/" + gameSettings->getTileset() + "/*", "xml", NULL);
|
||||
|
||||
//tech, load before map because of resources
|
||||
//checksum = Checksum();
|
||||
//file = "techs/" + gameSettings->getTech() + "/" + gameSettings->getTech() + ".xml";
|
||||
//checksum.addFile(file);
|
||||
// factions
|
||||
// resources
|
||||
//data.techCRC = checksum.getSum();
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),data.techCRC);
|
||||
data.techCRC = getFolderTreeContentsCheckSumRecursively("techs/" + gameSettings->getTech() + "/*", "xml", NULL);
|
||||
|
||||
//map
|
||||
Checksum checksum;
|
||||
string file = Map::getMapPath(gameSettings->getMap());
|
||||
checksum.addFile(file);
|
||||
data.mapCRC = checksum.getSum();
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] file = [%s] checksum = %d\n",__FILE__,__FUNCTION__,file.c_str(),data.mapCRC);
|
||||
|
||||
data.hasFogOfWar = Config::getInstance().getBool("FogOfWar");;
|
||||
}
|
||||
|
||||
bool NetworkMessageSynchNetworkGameData::receive(Socket* socket)
|
||||
{
|
||||
return NetworkMessage::receive(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void NetworkMessageSynchNetworkGameData::send(Socket* socket) const
|
||||
{
|
||||
assert(data.messageType==nmtSynchNetworkGameData);
|
||||
NetworkMessage::send(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameDataStatus
|
||||
// =====================================================
|
||||
|
||||
NetworkMessageSynchNetworkGameDataStatus::NetworkMessageSynchNetworkGameDataStatus(int32 mapCRC, int32 tilesetCRC, int32 techCRC, int8 hasFogOfWar)
|
||||
{
|
||||
data.messageType= nmtSynchNetworkGameDataStatus;
|
||||
|
||||
data.tilesetCRC = tilesetCRC;
|
||||
data.techCRC = techCRC;
|
||||
data.mapCRC = mapCRC;
|
||||
|
||||
data.hasFogOfWar = hasFogOfWar;
|
||||
}
|
||||
|
||||
bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket)
|
||||
{
|
||||
return NetworkMessage::receive(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void NetworkMessageSynchNetworkGameDataStatus::send(Socket* socket) const
|
||||
{
|
||||
assert(data.messageType==nmtSynchNetworkGameDataStatus);
|
||||
NetworkMessage::send(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameDataFileCRCCheck
|
||||
// =====================================================
|
||||
|
||||
NetworkMessageSynchNetworkGameDataFileCRCCheck::NetworkMessageSynchNetworkGameDataFileCRCCheck(int32 totalFileCount, int32 fileIndex, int32 fileCRC, const string fileName)
|
||||
{
|
||||
data.messageType= nmtSynchNetworkGameDataFileCRCCheck;
|
||||
|
||||
data.totalFileCount = totalFileCount;
|
||||
data.fileIndex = fileIndex;
|
||||
data.fileCRC = fileCRC;
|
||||
data.fileName = fileName;
|
||||
}
|
||||
|
||||
bool NetworkMessageSynchNetworkGameDataFileCRCCheck::receive(Socket* socket)
|
||||
{
|
||||
return NetworkMessage::receive(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void NetworkMessageSynchNetworkGameDataFileCRCCheck::send(Socket* socket) const
|
||||
{
|
||||
assert(data.messageType==nmtSynchNetworkGameDataFileCRCCheck);
|
||||
NetworkMessage::send(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameDataFileGet
|
||||
// =====================================================
|
||||
|
||||
NetworkMessageSynchNetworkGameDataFileGet::NetworkMessageSynchNetworkGameDataFileGet(const string fileName)
|
||||
{
|
||||
data.messageType= nmtSynchNetworkGameDataFileGet;
|
||||
|
||||
data.fileName = fileName;
|
||||
}
|
||||
|
||||
bool NetworkMessageSynchNetworkGameDataFileGet::receive(Socket* socket)
|
||||
{
|
||||
return NetworkMessage::receive(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void NetworkMessageSynchNetworkGameDataFileGet::send(Socket* socket) const
|
||||
{
|
||||
assert(data.messageType==nmtSynchNetworkGameDataFileGet);
|
||||
NetworkMessage::send(socket, &data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -33,10 +33,16 @@ enum NetworkMessageType{
|
|||
nmtCommandList,
|
||||
nmtText,
|
||||
nmtQuit,
|
||||
nmtSynchNetworkGameData,
|
||||
nmtSynchNetworkGameDataStatus,
|
||||
nmtSynchNetworkGameDataFileCRCCheck,
|
||||
nmtSynchNetworkGameDataFileGet,
|
||||
|
||||
nmtCount
|
||||
};
|
||||
|
||||
const int32 networkPacketMsgTypeSize = 6;
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessage
|
||||
// =====================================================
|
||||
|
@ -163,10 +169,11 @@ public:
|
|||
// Message to order a commands to several units
|
||||
// =====================================================
|
||||
|
||||
#pragma pack(push, 1)
|
||||
class NetworkMessageCommandList: public NetworkMessage{
|
||||
private:
|
||||
static const int maxCommandCount= 16*4;
|
||||
|
||||
|
||||
private:
|
||||
struct Data{
|
||||
int8 messageType;
|
||||
|
@ -182,7 +189,7 @@ public:
|
|||
NetworkMessageCommandList(int32 frameCount= -1);
|
||||
|
||||
bool addCommand(const NetworkCommand* networkCommand);
|
||||
|
||||
|
||||
void clear() {data.commandCount= 0;}
|
||||
int getCommandCount() const {return data.commandCount;}
|
||||
int getFrameCount() const {return data.frameCount;}
|
||||
|
@ -191,6 +198,7 @@ public:
|
|||
virtual bool receive(Socket* socket);
|
||||
virtual void send(Socket* socket) const;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageText
|
||||
|
@ -247,6 +255,164 @@ public:
|
|||
virtual void send(Socket* socket) const;
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameData
|
||||
//
|
||||
// Message sent at the beggining of a network game
|
||||
// =====================================================
|
||||
|
||||
class NetworkMessageSynchNetworkGameData: public NetworkMessage{
|
||||
|
||||
private:
|
||||
|
||||
static const int maxStringSize= 256;
|
||||
|
||||
private:
|
||||
struct Data{
|
||||
int8 messageType;
|
||||
|
||||
NetworkString<maxStringSize> map;
|
||||
NetworkString<maxStringSize> tileset;
|
||||
NetworkString<maxStringSize> tech;
|
||||
|
||||
int32 mapCRC;
|
||||
int32 tilesetCRC;
|
||||
int32 techCRC;
|
||||
int8 hasFogOfWar;
|
||||
};
|
||||
|
||||
private:
|
||||
Data data;
|
||||
|
||||
public:
|
||||
NetworkMessageSynchNetworkGameData() {};
|
||||
NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings);
|
||||
|
||||
virtual bool receive(Socket* socket);
|
||||
virtual void send(Socket* socket) const;
|
||||
|
||||
string getMap() const {return data.map.getString();}
|
||||
string getTileset() const {return data.tileset.getString();}
|
||||
string getTech() const {return data.tech.getString();}
|
||||
|
||||
int32 getMapCRC() const {return data.mapCRC;}
|
||||
int32 getTilesetCRC() const {return data.tilesetCRC;}
|
||||
int32 getTechCRC() const {return data.techCRC;}
|
||||
|
||||
int8 getFogOfWar() const { return data.hasFogOfWar; }
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameDataStatus
|
||||
//
|
||||
// Message sent at the beggining of a network game
|
||||
// =====================================================
|
||||
|
||||
class NetworkMessageSynchNetworkGameDataStatus: public NetworkMessage{
|
||||
|
||||
private:
|
||||
|
||||
static const int maxStringSize= 256;
|
||||
|
||||
private:
|
||||
struct Data{
|
||||
int8 messageType;
|
||||
|
||||
int32 mapCRC;
|
||||
int32 tilesetCRC;
|
||||
int32 techCRC;
|
||||
|
||||
int8 hasFogOfWar;
|
||||
};
|
||||
|
||||
private:
|
||||
Data data;
|
||||
|
||||
public:
|
||||
NetworkMessageSynchNetworkGameDataStatus() {};
|
||||
NetworkMessageSynchNetworkGameDataStatus(int32 mapCRC, int32 tilesetCRC, int32 techCRC, int8 hasFogOfWar);
|
||||
|
||||
virtual bool receive(Socket* socket);
|
||||
virtual void send(Socket* socket) const;
|
||||
|
||||
int32 getMapCRC() const {return data.mapCRC;}
|
||||
int32 getTilesetCRC() const {return data.tilesetCRC;}
|
||||
int32 getTechCRC() const {return data.techCRC;}
|
||||
|
||||
int8 getFogOfWar() const { return data.hasFogOfWar; }
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameDataFileCRCCheck
|
||||
//
|
||||
// Message sent at the beggining of a network game
|
||||
// =====================================================
|
||||
|
||||
class NetworkMessageSynchNetworkGameDataFileCRCCheck: public NetworkMessage{
|
||||
|
||||
private:
|
||||
|
||||
static const int maxStringSize= 256;
|
||||
|
||||
private:
|
||||
struct Data{
|
||||
int8 messageType;
|
||||
|
||||
int32 totalFileCount;
|
||||
int32 fileIndex;
|
||||
int32 fileCRC;
|
||||
NetworkString<maxStringSize> fileName;
|
||||
};
|
||||
|
||||
private:
|
||||
Data data;
|
||||
|
||||
public:
|
||||
NetworkMessageSynchNetworkGameDataFileCRCCheck() {};
|
||||
NetworkMessageSynchNetworkGameDataFileCRCCheck(int32 totalFileCount, int32 fileIndex, int32 fileCRC, const string fileName);
|
||||
|
||||
virtual bool receive(Socket* socket);
|
||||
virtual void send(Socket* socket) const;
|
||||
|
||||
int32 getTotalFileCount() const {return data.totalFileCount;}
|
||||
int32 getFileIndex() const {return data.fileIndex;}
|
||||
int32 getFileCRC() const {return data.fileCRC;}
|
||||
string getFileName() const {return data.fileName.getString();}
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class NetworkMessageSynchNetworkGameDataFileGet
|
||||
//
|
||||
// Message sent at the beggining of a network game
|
||||
// =====================================================
|
||||
|
||||
class NetworkMessageSynchNetworkGameDataFileGet: public NetworkMessage{
|
||||
|
||||
private:
|
||||
|
||||
static const int maxStringSize= 256;
|
||||
|
||||
private:
|
||||
struct Data{
|
||||
int8 messageType;
|
||||
|
||||
NetworkString<maxStringSize> fileName;
|
||||
};
|
||||
|
||||
private:
|
||||
Data data;
|
||||
|
||||
public:
|
||||
NetworkMessageSynchNetworkGameDataFileGet() {};
|
||||
NetworkMessageSynchNetworkGameDataFileGet(const string fileName);
|
||||
|
||||
virtual bool receive(Socket* socket);
|
||||
virtual void send(Socket* socket) const;
|
||||
|
||||
string getFileName() const {return data.fileName.getString();}
|
||||
};
|
||||
|
||||
|
||||
}}//end namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -50,6 +50,7 @@ enum NetworkCommandType{
|
|||
nctSetMeetingPoint
|
||||
};
|
||||
|
||||
#pragma pack(push, 2)
|
||||
class NetworkCommand{
|
||||
private:
|
||||
int16 networkCommandType;
|
||||
|
@ -71,6 +72,7 @@ public:
|
|||
int getUnitTypeId() const {return unitTypeId;}
|
||||
int getTargetId() const {return targetId;}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
}}//end namespace
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
|||
#include "lang.h"
|
||||
|
||||
#include "leak_dumper.h"
|
||||
#include "logger.h"
|
||||
#include <time.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Shared::Platform;
|
||||
|
@ -32,6 +34,9 @@ namespace Glest{ namespace Game{
|
|||
// =====================================================
|
||||
|
||||
ServerInterface::ServerInterface(){
|
||||
gameHasBeenInitiated = false;
|
||||
gameSettingsUpdateCount = 0;
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
slots[i]= NULL;
|
||||
}
|
||||
|
@ -40,23 +45,39 @@ ServerInterface::ServerInterface(){
|
|||
}
|
||||
|
||||
ServerInterface::~ServerInterface(){
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
delete slots[i];
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ServerInterface::addSlot(int playerIndex){
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
assert(playerIndex>=0 && playerIndex<GameConstants::maxPlayers);
|
||||
|
||||
delete slots[playerIndex];
|
||||
slots[playerIndex]= new ConnectionSlot(this, playerIndex);
|
||||
updateListen();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ServerInterface::removeSlot(int playerIndex){
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
delete slots[playerIndex];
|
||||
slots[playerIndex]= NULL;
|
||||
updateListen();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
ConnectionSlot* ServerInterface::getSlot(int playerIndex){
|
||||
|
@ -65,7 +86,7 @@ ConnectionSlot* ServerInterface::getSlot(int playerIndex){
|
|||
|
||||
int ServerInterface::getConnectedSlotCount(){
|
||||
int connectedSlotCount= 0;
|
||||
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
if(slots[i]!= NULL){
|
||||
++connectedSlotCount;
|
||||
|
@ -74,44 +95,138 @@ int ServerInterface::getConnectedSlotCount(){
|
|||
return connectedSlotCount;
|
||||
}
|
||||
|
||||
void ServerInterface::update(){
|
||||
|
||||
void ServerInterface::update()
|
||||
{
|
||||
std::map<int,bool> socketTriggeredList;
|
||||
//update all slots
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
if(slots[i]!= NULL){
|
||||
slots[i]->update();
|
||||
for(int i= 0; i < GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
if(connectionSlot != NULL && connectionSlot->getSocket() != NULL &&
|
||||
slots[i]->getSocket()->getSocketId() > 0)
|
||||
{
|
||||
socketTriggeredList[connectionSlot->getSocket()->getSocketId()] = false;
|
||||
}
|
||||
}
|
||||
|
||||
//process text messages
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
if(gameHasBeenInitiated == false || socketTriggeredList.size() > 0)
|
||||
{
|
||||
if(gameHasBeenInitiated && Socket::enableDebugText) printf("In [%s::%s] socketTriggeredList.size() = %d\n",__FILE__,__FUNCTION__,socketTriggeredList.size());
|
||||
|
||||
if(connectionSlot!= NULL){
|
||||
if(connectionSlot->isConnected()){
|
||||
if(connectionSlot->getNextMessageType()==nmtText){
|
||||
NetworkMessageText networkMessageText;
|
||||
if(connectionSlot->receiveMessage(&networkMessageText)){
|
||||
broadcastMessage(&networkMessageText, i);
|
||||
chatText= networkMessageText.getText();
|
||||
chatSender= networkMessageText.getSender();
|
||||
chatTeamIndex= networkMessageText.getTeamIndex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool hasData = Socket::hasDataToRead(socketTriggeredList);
|
||||
|
||||
if(hasData && Socket::enableDebugText) printf("In [%s::%s] hasData == true\n",__FILE__,__FUNCTION__);
|
||||
|
||||
if(gameHasBeenInitiated == false || hasData == true)
|
||||
{
|
||||
//if(gameHasBeenInitiated && Socket::enableDebugText) printf("In [%s::%s] hasData == true\n",__FILE__,__FUNCTION__);
|
||||
|
||||
//std::vector<TeamMessageData> vctTeamMessages;
|
||||
|
||||
//update all slots
|
||||
bool checkForNewClients = true;
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
if(connectionSlot != NULL &&
|
||||
(gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true)))
|
||||
{
|
||||
if(connectionSlot->isConnected() == false ||
|
||||
(socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true))
|
||||
{
|
||||
if(gameHasBeenInitiated && Socket::enableDebugText) printf("In [%s::%s] socketTriggeredList[i] = %i\n",__FILE__,__FUNCTION__,(socketTriggeredList[connectionSlot->getSocket()->getSocketId()] ? 1 : 0));
|
||||
|
||||
if(connectionSlot->isConnected())
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] calling slots[i]->update() for slot = %d socketId = %d\n",
|
||||
__FILE__,__FUNCTION__,i,connectionSlot->getSocket()->getSocketId());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(gameHasBeenInitiated && Socket::enableDebugText) printf("In [%s::%s] slot = %d getSocket() == NULL\n",__FILE__,__FUNCTION__,i);
|
||||
}
|
||||
connectionSlot->update(checkForNewClients);
|
||||
|
||||
// This means no clients are trying to connect at the moment
|
||||
if(connectionSlot != NULL && connectionSlot->getSocket() == NULL)
|
||||
{
|
||||
checkForNewClients = false;
|
||||
}
|
||||
|
||||
if(connectionSlot != NULL &&
|
||||
//connectionSlot->isConnected() == true &&
|
||||
connectionSlot->getChatText().empty() == false)
|
||||
{
|
||||
chatText = connectionSlot->getChatText();
|
||||
chatSender = connectionSlot->getChatSender();
|
||||
chatTeamIndex = connectionSlot->getChatTeamIndex();
|
||||
|
||||
//TeamMessageData teamMessageData;
|
||||
//teamMessageData.chatSender = connectionSlot->getChatSender();
|
||||
//teamMessageData.chatText = connectionSlot->getChatText();
|
||||
//teamMessageData.chatTeamIndex = connectionSlot->getChatTeamIndex();
|
||||
//teamMessageData.sourceTeamIndex = i;
|
||||
//vctTeamMessages.push_back(teamMessageData);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] #1 about to broadcast nmtText chatText [%s] chatSender [%s] chatTeamIndex = %d for SlotIndex# %d\n",__FILE__,__FUNCTION__,chatText.c_str(),chatSender.c_str(),chatTeamIndex,i);
|
||||
|
||||
NetworkMessageText networkMessageText(chatText,chatSender,chatTeamIndex);
|
||||
broadcastMessage(&networkMessageText, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//process text messages
|
||||
if(chatText.empty() == true)
|
||||
{
|
||||
chatText.clear();
|
||||
chatSender.clear();
|
||||
chatTeamIndex= -1;
|
||||
|
||||
for(int i= 0; i< GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(connectionSlot!= NULL &&
|
||||
(gameHasBeenInitiated == false || (connectionSlot->getSocket() != NULL && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true)))
|
||||
{
|
||||
if(connectionSlot->isConnected() && socketTriggeredList[connectionSlot->getSocket()->getSocketId()] == true)
|
||||
{
|
||||
if(connectionSlot->getSocket() != NULL && Socket::enableDebugText) printf("In [%s::%s] calling connectionSlot->getNextMessageType() for slots[i]->getSocket()->getSocketId() = %d\n",
|
||||
__FILE__,__FUNCTION__,connectionSlot->getSocket()->getSocketId());
|
||||
|
||||
if(connectionSlot->getNextMessageType() == nmtText)
|
||||
{
|
||||
NetworkMessageText networkMessageText;
|
||||
if(connectionSlot->receiveMessage(&networkMessageText))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] #2 about to broadcast nmtText msg for SlotIndex# %d\n",__FILE__,__FUNCTION__,i);
|
||||
|
||||
broadcastMessage(&networkMessageText, i);
|
||||
chatText= networkMessageText.getText();
|
||||
chatSender= networkMessageText.getSender();
|
||||
chatTeamIndex= networkMessageText.getTeamIndex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerInterface::updateKeyframe(int frameCount){
|
||||
|
||||
NetworkMessageCommandList networkMessageCommandList(frameCount);
|
||||
|
||||
|
||||
//build command list, remove commands from requested and add to pending
|
||||
while(!requestedCommands.empty()){
|
||||
if(networkMessageCommandList.addCommand(&requestedCommands.back())){
|
||||
|
@ -128,51 +243,100 @@ void ServerInterface::updateKeyframe(int frameCount){
|
|||
}
|
||||
|
||||
void ServerInterface::waitUntilReady(Checksum* checksum){
|
||||
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s] START\n",__FUNCTION__);
|
||||
|
||||
Logger &logger= Logger::getInstance();
|
||||
gameHasBeenInitiated = true;
|
||||
|
||||
Chrono chrono;
|
||||
bool allReady= false;
|
||||
|
||||
chrono.start();
|
||||
|
||||
//wait until we get a ready message from all clients
|
||||
while(!allReady){
|
||||
|
||||
while(allReady == false)
|
||||
{
|
||||
vector<string> waitingForHosts;
|
||||
allReady= true;
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(connectionSlot!=NULL){
|
||||
if(!connectionSlot->isReady()){
|
||||
NetworkMessageType networkMessageType= connectionSlot->getNextMessageType();
|
||||
if(connectionSlot != NULL && connectionSlot->isConnected() == true)
|
||||
{
|
||||
if(connectionSlot->isReady() == false)
|
||||
{
|
||||
NetworkMessageType networkMessageType= connectionSlot->getNextMessageType(true);
|
||||
NetworkMessageReady networkMessageReady;
|
||||
|
||||
if(networkMessageType==nmtReady && connectionSlot->receiveMessage(&networkMessageReady)){
|
||||
if(networkMessageType == nmtReady &&
|
||||
connectionSlot->receiveMessage(&networkMessageReady))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s] networkMessageType==nmtReady\n",__FUNCTION__);
|
||||
|
||||
connectionSlot->setReady();
|
||||
}
|
||||
else if(networkMessageType!=nmtInvalid){
|
||||
else if(networkMessageType != nmtInvalid)
|
||||
{
|
||||
throw runtime_error("Unexpected network message: " + intToStr(networkMessageType));
|
||||
}
|
||||
|
||||
waitingForHosts.push_back(connectionSlot->getHostName());
|
||||
|
||||
allReady= false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check for timeout
|
||||
if(chrono.getMillis()>readyWaitTimeout){
|
||||
throw runtime_error("Timeout waiting for clients");
|
||||
if(allReady == false)
|
||||
{
|
||||
if(chrono.getMillis() > readyWaitTimeout)
|
||||
{
|
||||
throw runtime_error("Timeout waiting for clients");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(chrono.getMillis() % 1000 == 0)
|
||||
{
|
||||
string waitForHosts = "";
|
||||
for(int i = 0; i < waitingForHosts.size(); i++)
|
||||
{
|
||||
if(waitForHosts != "")
|
||||
{
|
||||
waitForHosts += ", ";
|
||||
}
|
||||
waitForHosts += waitingForHosts[i];
|
||||
}
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"Waiting for network: %d of %d max seconds (waiting for: %s)",int(chrono.getMillis() / 1000),int(readyWaitTimeout / 1000),waitForHosts.c_str());
|
||||
logger.add(szBuf, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//send ready message after, so clients start delayed
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
NetworkMessageReady networkMessageReady(checksum->getSum());
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(connectionSlot!=NULL){
|
||||
// FOR TESTING ONLY - delay to see the client count up while waiting
|
||||
//sleep(5000);
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s] PART B (telling client we are ready!\n",__FUNCTION__);
|
||||
|
||||
//send ready message after, so clients start delayed
|
||||
for(int i= 0; i < GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
NetworkMessageReady networkMessageReady(checksum->getSum());
|
||||
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
if(connectionSlot!=NULL)
|
||||
{
|
||||
connectionSlot->sendMessage(&networkMessageReady);
|
||||
}
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s] END\n",__FUNCTION__);
|
||||
}
|
||||
|
||||
void ServerInterface::sendTextMessage(const string &text, int teamIndex){
|
||||
|
@ -180,7 +344,15 @@ void ServerInterface::sendTextMessage(const string &text, int teamIndex){
|
|||
broadcastMessage(&networkMessageText);
|
||||
}
|
||||
|
||||
void ServerInterface::quitGame(){
|
||||
void ServerInterface::quitGame(bool userManuallyQuit)
|
||||
{
|
||||
if(userManuallyQuit == true)
|
||||
{
|
||||
string sQuitText = getHostName() + " has chosen to leave the game!";
|
||||
NetworkMessageText networkMessageText(sQuitText,getHostName(),-1);
|
||||
broadcastMessage(&networkMessageText, -1);
|
||||
}
|
||||
|
||||
NetworkMessageQuit networkMessageQuit;
|
||||
broadcastMessage(&networkMessageQuit);
|
||||
}
|
||||
|
@ -191,12 +363,13 @@ string ServerInterface::getNetworkStatus() const{
|
|||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
|
||||
str+= intToStr(i)+ ": ";
|
||||
|
||||
if(connectionSlot!= NULL){
|
||||
if(connectionSlot->isConnected()){
|
||||
str+= connectionSlot->getName();
|
||||
|
||||
str+= connectionSlot->getName();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -209,31 +382,96 @@ string ServerInterface::getNetworkStatus() const{
|
|||
return str;
|
||||
}
|
||||
|
||||
void ServerInterface::launchGame(const GameSettings* gameSettings){
|
||||
NetworkMessageLaunch networkMessageLaunch(gameSettings);
|
||||
broadcastMessage(&networkMessageLaunch);
|
||||
bool ServerInterface::launchGame(const GameSettings* gameSettings){
|
||||
|
||||
bool bOkToStart = true;
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot *connectionSlot= slots[i];
|
||||
if(connectionSlot != NULL &&
|
||||
connectionSlot->getAllowDownloadDataSynch() == true &&
|
||||
connectionSlot->isConnected())
|
||||
{
|
||||
if(connectionSlot->getNetworkGameDataSynchCheckOk() == false)
|
||||
{
|
||||
bOkToStart = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bOkToStart == true)
|
||||
{
|
||||
NetworkMessageLaunch networkMessageLaunch(gameSettings);
|
||||
broadcastMessage(&networkMessageLaunch);
|
||||
}
|
||||
|
||||
return bOkToStart;
|
||||
}
|
||||
|
||||
void ServerInterface::broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot){
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(i != excludeSlot && connectionSlot != NULL)
|
||||
{
|
||||
if(connectionSlot->isConnected())
|
||||
{
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] before sendMessage\n",__FILE__,__FUNCTION__);
|
||||
connectionSlot->sendMessage(networkMessage);
|
||||
}
|
||||
else if(gameHasBeenInitiated == true)
|
||||
{
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] #1 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,i);
|
||||
removeSlot(i);
|
||||
}
|
||||
}
|
||||
else if(i == excludeSlot && gameHasBeenInitiated == true &&
|
||||
connectionSlot != NULL && connectionSlot->isConnected() == false)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] #2 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,i);
|
||||
removeSlot(i);
|
||||
}
|
||||
}
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ServerInterface::broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot){
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
ConnectionSlot* connectionSlot= slots[i];
|
||||
|
||||
if(i!= excludeSlot && connectionSlot!= NULL){
|
||||
if(connectionSlot->isConnected()){
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] before sendMessage\n",__FILE__,__FUNCTION__);
|
||||
|
||||
connectionSlot->sendMessage(networkMessage);
|
||||
}
|
||||
else{
|
||||
removeSlot(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ServerInterface::updateListen(){
|
||||
void ServerInterface::updateListen()
|
||||
{
|
||||
int openSlotCount= 0;
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||
if(slots[i]!= NULL && !slots[i]->isConnected()){
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
if(slots[i] != NULL && slots[i]->isConnected() == false)
|
||||
{
|
||||
++openSlotCount;
|
||||
}
|
||||
}
|
||||
|
@ -241,4 +479,92 @@ void ServerInterface::updateListen(){
|
|||
serverSocket.listen(openSlotCount);
|
||||
}
|
||||
|
||||
void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START gameSettingsUpdateCount = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount);
|
||||
|
||||
if(getAllowGameDataSynchCheck() == true)
|
||||
{
|
||||
if(waitForClientAck == true && gameSettingsUpdateCount > 0)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] Waiting for client acks #1\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStart = time(NULL);
|
||||
bool gotAckFromAllClients = false;
|
||||
while(gotAckFromAllClients == false && difftime(time(NULL),tStart) <= 5)
|
||||
{
|
||||
gotAckFromAllClients = true;
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot *connectionSlot = slots[i];
|
||||
if(connectionSlot != NULL && connectionSlot->isConnected())
|
||||
{
|
||||
if(connectionSlot->getReceivedNetworkGameStatus() == false)
|
||||
{
|
||||
gotAckFromAllClients = false;
|
||||
}
|
||||
|
||||
connectionSlot->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot *connectionSlot = slots[i];
|
||||
if(connectionSlot != NULL && connectionSlot->isConnected())
|
||||
{
|
||||
connectionSlot->setReceivedNetworkGameStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
gameSettings = *serverGameSettings;
|
||||
|
||||
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(getGameSettings());
|
||||
broadcastMessageToConnectedClients(&networkMessageSynchNetworkGameData);
|
||||
|
||||
if(waitForClientAck == true)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] Waiting for client acks #2\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStart = time(NULL);
|
||||
bool gotAckFromAllClients = false;
|
||||
while(gotAckFromAllClients == false && difftime(time(NULL),tStart) <= 5)
|
||||
{
|
||||
gotAckFromAllClients = true;
|
||||
for(int i= 0; i<GameConstants::maxPlayers; ++i)
|
||||
{
|
||||
ConnectionSlot *connectionSlot = slots[i];
|
||||
if(connectionSlot != NULL && connectionSlot->isConnected())
|
||||
{
|
||||
if(connectionSlot->getReceivedNetworkGameStatus() == false)
|
||||
{
|
||||
gotAckFromAllClients = false;
|
||||
}
|
||||
|
||||
connectionSlot->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gameSettingsUpdateCount++;
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END\n",__FILE__,__FUNCTION__);
|
||||
}
|
||||
|
||||
void ServerInterface::close()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
||||
|
||||
//serverSocket = ServerSocket();
|
||||
}
|
||||
|
||||
bool ServerInterface::getFogOfWar()
|
||||
{
|
||||
return Config::getInstance().getBool("FogOfWar");
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -28,10 +28,21 @@ namespace Glest{ namespace Game{
|
|||
// class ServerInterface
|
||||
// =====================================================
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string chatText;
|
||||
string chatSender;
|
||||
int chatTeamIndex;
|
||||
int sourceTeamIndex;
|
||||
|
||||
} TeamMessageData;
|
||||
|
||||
class ServerInterface: public GameNetworkInterface{
|
||||
private:
|
||||
ConnectionSlot* slots[GameConstants::maxPlayers];
|
||||
ServerSocket serverSocket;
|
||||
bool gameHasBeenInitiated;
|
||||
int gameSettingsUpdateCount;
|
||||
|
||||
public:
|
||||
ServerInterface();
|
||||
|
@ -39,6 +50,7 @@ public:
|
|||
|
||||
virtual Socket* getSocket() {return &serverSocket;}
|
||||
virtual const Socket* getSocket() const {return &serverSocket;}
|
||||
virtual void close();
|
||||
|
||||
//message processing
|
||||
virtual void update();
|
||||
|
@ -48,7 +60,7 @@ public:
|
|||
|
||||
// message sending
|
||||
virtual void sendTextMessage(const string &text, int teamIndex);
|
||||
virtual void quitGame();
|
||||
virtual void quitGame(bool userManuallyQuit);
|
||||
|
||||
//misc
|
||||
virtual string getNetworkStatus() const;
|
||||
|
@ -59,11 +71,14 @@ public:
|
|||
ConnectionSlot* getSlot(int playerIndex);
|
||||
int getConnectedSlotCount();
|
||||
|
||||
void launchGame(const GameSettings* gameSettings);
|
||||
bool launchGame(const GameSettings* gameSettings);
|
||||
virtual void setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck = false);
|
||||
virtual bool getFogOfWar();
|
||||
|
||||
private:
|
||||
void broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot= -1);
|
||||
void updateListen();
|
||||
void broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot = -1);
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace Glest{ namespace Game{
|
|||
// =====================================================
|
||||
|
||||
void Faction::init(
|
||||
const FactionType *factionType, ControlType control, TechTree *techTree,
|
||||
const FactionType *factionType, ControlType control, TechTree *techTree,
|
||||
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources)
|
||||
{
|
||||
this->control= control;
|
||||
|
@ -83,7 +83,7 @@ int Faction::getStoreAmount(const ResourceType *rt) const{
|
|||
bool Faction::getCpuControl() const{
|
||||
return control==ctCpuEasy ||control==ctCpu || control==ctCpuUltra|| control==ctCpuMega;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==================== upgrade manager ====================
|
||||
|
||||
|
@ -106,9 +106,9 @@ void Faction::finishUpgrade(const UpgradeType *ut){
|
|||
|
||||
//checks if all required units and upgrades are present
|
||||
bool Faction::reqsOk(const RequirableType *rt) const{
|
||||
|
||||
|
||||
//required units
|
||||
for(int i=0; i<rt->getUnitReqCount(); ++i){
|
||||
for(int i=0; i<rt->getUnitReqCount(); ++i){
|
||||
bool found=false;
|
||||
for(int j=0; j<getUnitCount(); ++j){
|
||||
Unit *unit= getUnit(j);
|
||||
|
@ -125,7 +125,7 @@ bool Faction::reqsOk(const RequirableType *rt) const{
|
|||
|
||||
//required upgrades
|
||||
for(int i=0; i<rt->getUpgradeReqCount(); ++i){
|
||||
if(!upgradeManager.isUpgraded(rt->getUpgradeReq(i))){
|
||||
if(!upgradeManager.isUpgraded(rt->getUpgradeReq(i))){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ bool Faction::reqsOk(const RequirableType *rt) const{
|
|||
}
|
||||
|
||||
bool Faction::reqsOk(const CommandType *ct) const{
|
||||
|
||||
|
||||
if(ct->getProduced()!=NULL && !reqsOk(ct->getProduced())){
|
||||
return false;
|
||||
}
|
||||
|
@ -145,113 +145,134 @@ bool Faction::reqsOk(const CommandType *ct) const{
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return reqsOk(static_cast<const RequirableType*>(ct));
|
||||
|
||||
return reqsOk(static_cast<const RequirableType*>(ct));
|
||||
}
|
||||
|
||||
// ================== cost application ==================
|
||||
|
||||
//apply costs except static production (start building/production)
|
||||
bool Faction::applyCosts(const ProducibleType *p){
|
||||
|
||||
|
||||
if(!checkCosts(p)){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//for each unit cost spend it
|
||||
//pass 2, decrease resources, except negative static costs (ie: farms)
|
||||
for(int i=0; i<p->getCostCount(); ++i){
|
||||
for(int i=0; i<p->getCostCount(); ++i)
|
||||
{
|
||||
const ResourceType *rt= p->getCost(i)->getType();
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
if((cost>0 || rt->getClass()!=rcStatic) && rt->getClass()!=rcConsumable){
|
||||
if((cost > 0 || (rt->getClass() != rcStatic)) && rt->getClass() != rcConsumable)
|
||||
{
|
||||
incResourceAmount(rt, -(cost));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//apply discount (when a morph ends)
|
||||
void Faction::applyDiscount(const ProducibleType *p, int discount){
|
||||
void Faction::applyDiscount(const ProducibleType *p, int discount)
|
||||
{
|
||||
//increase resources
|
||||
for(int i=0; i<p->getCostCount(); ++i){
|
||||
for(int i=0; i<p->getCostCount(); ++i)
|
||||
{
|
||||
const ResourceType *rt= p->getCost(i)->getType();
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
if((cost>0 || rt->getClass()!=rcStatic) && rt->getClass()!=rcConsumable){
|
||||
if((cost > 0 || (rt->getClass() != rcStatic)) && rt->getClass() != rcConsumable)
|
||||
{
|
||||
incResourceAmount(rt, cost*discount/100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//apply static production (for starting units)
|
||||
void Faction::applyStaticCosts(const ProducibleType *p){
|
||||
|
||||
void Faction::applyStaticCosts(const ProducibleType *p)
|
||||
{
|
||||
//decrease static resources
|
||||
for(int i=0; i<p->getCostCount(); ++i){
|
||||
for(int i=0; i<p->getCostCount(); ++i)
|
||||
{
|
||||
const ResourceType *rt= p->getCost(i)->getType();
|
||||
if(rt->getClass()==rcStatic){
|
||||
if(rt->getClass() == rcStatic)
|
||||
{
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
if(cost>0){
|
||||
if(cost > 0)
|
||||
{
|
||||
incResourceAmount(rt, -cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//apply static production (when a mana source is done)
|
||||
void Faction::applyStaticProduction(const ProducibleType *p){
|
||||
|
||||
void Faction::applyStaticProduction(const ProducibleType *p)
|
||||
{
|
||||
//decrease static resources
|
||||
for(int i=0; i<p->getCostCount(); ++i){
|
||||
for(int i=0; i<p->getCostCount(); ++i)
|
||||
{
|
||||
const ResourceType *rt= p->getCost(i)->getType();
|
||||
if(rt->getClass()==rcStatic){
|
||||
if(rt->getClass() == rcStatic)
|
||||
{
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
if(cost<0){
|
||||
if(cost < 0)
|
||||
{
|
||||
incResourceAmount(rt, -cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//deapply all costs except static production (usually when a building is cancelled)
|
||||
void Faction::deApplyCosts(const ProducibleType *p){
|
||||
|
||||
void Faction::deApplyCosts(const ProducibleType *p)
|
||||
{
|
||||
//increase resources
|
||||
for(int i=0; i<p->getCostCount(); ++i){
|
||||
for(int i=0; i<p->getCostCount(); ++i)
|
||||
{
|
||||
const ResourceType *rt= p->getCost(i)->getType();
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
if((cost>0 || rt->getClass()!=rcStatic) && rt->getClass()!=rcConsumable){
|
||||
if((cost > 0 || (rt->getClass() != rcStatic)) && rt->getClass() != rcConsumable)
|
||||
{
|
||||
incResourceAmount(rt, cost);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//deapply static costs (usually when a unit dies)
|
||||
void Faction::deApplyStaticCosts(const ProducibleType *p){
|
||||
|
||||
void Faction::deApplyStaticCosts(const ProducibleType *p)
|
||||
{
|
||||
//decrease resources
|
||||
for(int i=0; i<p->getCostCount(); ++i){
|
||||
for(int i=0; i<p->getCostCount(); ++i)
|
||||
{
|
||||
const ResourceType *rt= p->getCost(i)->getType();
|
||||
if(rt->getClass()==rcStatic){
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
incResourceAmount(rt, cost);
|
||||
}
|
||||
if(rt->getClass() == rcStatic)
|
||||
{
|
||||
if(rt->getRecoup_cost() == true)
|
||||
{
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
incResourceAmount(rt, cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//deapply static costs, but not negative costs, for when building gets killed
|
||||
void Faction::deApplyStaticConsumption(const ProducibleType *p){
|
||||
|
||||
void Faction::deApplyStaticConsumption(const ProducibleType *p)
|
||||
{
|
||||
//decrease resources
|
||||
for(int i=0; i<p->getCostCount(); ++i){
|
||||
for(int i=0; i<p->getCostCount(); ++i)
|
||||
{
|
||||
const ResourceType *rt= p->getCost(i)->getType();
|
||||
if(rt->getClass()==rcStatic){
|
||||
if(rt->getClass() == rcStatic)
|
||||
{
|
||||
int cost= p->getCost(i)->getAmount();
|
||||
if(cost>0){
|
||||
if(cost>0)
|
||||
{
|
||||
incResourceAmount(rt, cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +300,7 @@ void Faction::applyCostsOnInterval(){
|
|||
const Resource *resource= unit->getType()->getCost(k);
|
||||
if(resource->getType()->getClass()==rcConsumable && resource->getAmount()>0){
|
||||
incResourceAmount(resource->getType(), -resource->getAmount());
|
||||
|
||||
|
||||
//decrease unit hp
|
||||
if(getResource(resource->getType())->getAmount()<0){
|
||||
resetResourceAmount(resource->getType());
|
||||
|
@ -296,7 +317,7 @@ void Faction::applyCostsOnInterval(){
|
|||
}
|
||||
|
||||
bool Faction::checkCosts(const ProducibleType *pt){
|
||||
|
||||
|
||||
//for each unit cost check if enough resources
|
||||
for(int i=0; i<pt->getCostCount(); ++i){
|
||||
const ResourceType *rt= pt->getCost(i)->getType();
|
||||
|
@ -304,7 +325,7 @@ bool Faction::checkCosts(const ProducibleType *pt){
|
|||
if(cost>0){
|
||||
int available= getResource(rt)->getAmount();
|
||||
if(cost>available){
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -320,12 +341,16 @@ bool Faction::isAlly(const Faction *faction){
|
|||
|
||||
// ================== misc ==================
|
||||
|
||||
void Faction::incResourceAmount(const ResourceType *rt, int amount){
|
||||
for(int i=0; i<resources.size(); ++i){
|
||||
void Faction::incResourceAmount(const ResourceType *rt, int amount)
|
||||
{
|
||||
for(int i=0; i<resources.size(); ++i)
|
||||
{
|
||||
Resource *r= &resources[i];
|
||||
if(r->getType()==rt){
|
||||
if(r->getType()==rt)
|
||||
{
|
||||
r->setAmount(r->getAmount()+amount);
|
||||
if(r->getType()->getClass()!=rcStatic && r->getAmount()>getStoreAmount(rt)){
|
||||
if(r->getType()->getClass() != rcStatic && r->getAmount()>getStoreAmount(rt))
|
||||
{
|
||||
r->setAmount(getStoreAmount(rt));
|
||||
}
|
||||
return;
|
||||
|
@ -368,7 +393,7 @@ void Faction::removeUnit(Unit *unit){
|
|||
return;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void Faction::addStore(const UnitType *unitType){
|
||||
|
@ -396,11 +421,14 @@ void Faction::removeStore(const UnitType *unitType){
|
|||
limitResourcesToStore();
|
||||
}
|
||||
|
||||
void Faction::limitResourcesToStore(){
|
||||
for(int i=0; i<resources.size(); ++i){
|
||||
void Faction::limitResourcesToStore()
|
||||
{
|
||||
for(int i=0; i<resources.size(); ++i)
|
||||
{
|
||||
Resource *r= &resources[i];
|
||||
Resource *s= &store[i];
|
||||
if(r->getType()->getClass()!=rcStatic && r->getAmount()>s->getAmount()){
|
||||
if(r->getType()->getClass() != rcStatic && r->getAmount()>s->getAmount())
|
||||
{
|
||||
r->setAmount(s->getAmount());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
@ -254,7 +254,7 @@ public:
|
|||
//command related
|
||||
bool anyCommand() const;
|
||||
Command *getCurrCommand() const;
|
||||
uint getCommandSize() const;
|
||||
unsigned int getCommandSize() const;
|
||||
CommandResult giveCommand(Command *command); //give a command
|
||||
CommandResult finishCommand(); //command finished
|
||||
CommandResult cancelCommand(); //cancel canceled
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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 "resource_type.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "util.h"
|
||||
#include "element_type.h"
|
||||
#include "logger.h"
|
||||
#include "renderer.h"
|
||||
|
@ -33,9 +33,12 @@ void ResourceType::load(const string &dir, Checksum* checksum){
|
|||
string path, str;
|
||||
Renderer &renderer= Renderer::getInstance();
|
||||
|
||||
try{
|
||||
try
|
||||
{
|
||||
recoup_cost = true;
|
||||
|
||||
name= lastDir(dir);
|
||||
|
||||
|
||||
Logger::getInstance().add("Resource type: "+ formatString(name), true);
|
||||
path= dir+"/"+name+".xml";
|
||||
|
||||
|
@ -55,46 +58,64 @@ void ResourceType::load(const string &dir, Checksum* checksum){
|
|||
const XmlNode *typeNode= resourceNode->getChild("type");
|
||||
resourceClass= strToRc(typeNode->getAttribute("value")->getRestrictedValue());
|
||||
|
||||
switch(resourceClass){
|
||||
case rcTech:{
|
||||
//model
|
||||
const XmlNode *modelNode= typeNode->getChild("model");
|
||||
string path=dir+"/" + modelNode->getAttribute("path")->getRestrictedValue();
|
||||
|
||||
model= renderer.newModel(rsGame);
|
||||
model->load(path);
|
||||
|
||||
//default resources
|
||||
const XmlNode *defaultAmountNode= typeNode->getChild("default-amount");
|
||||
defResPerPatch= defaultAmountNode->getAttribute("value")->getIntValue();
|
||||
|
||||
//resource number
|
||||
const XmlNode *resourceNumberNode= typeNode->getChild("resource-number");
|
||||
resourceNumber= resourceNumberNode->getAttribute("value")->getIntValue();
|
||||
|
||||
}
|
||||
break;
|
||||
switch(resourceClass)
|
||||
{
|
||||
case rcTech:
|
||||
{
|
||||
//model
|
||||
const XmlNode *modelNode= typeNode->getChild("model");
|
||||
string path=dir+"/" + modelNode->getAttribute("path")->getRestrictedValue();
|
||||
|
||||
case rcTileset:{
|
||||
//resource number
|
||||
const XmlNode *defaultAmountNode= typeNode->getChild("default-amount");
|
||||
defResPerPatch= defaultAmountNode->getAttribute("value")->getIntValue();
|
||||
model= renderer.newModel(rsGame);
|
||||
model->load(path);
|
||||
|
||||
//resource number
|
||||
const XmlNode *tilesetObjectNode= typeNode->getChild("tileset-object");
|
||||
tilesetObject= tilesetObjectNode->getAttribute("value")->getIntValue();
|
||||
//default resources
|
||||
const XmlNode *defaultAmountNode= typeNode->getChild("default-amount");
|
||||
defResPerPatch= defaultAmountNode->getAttribute("value")->getIntValue();
|
||||
|
||||
//resource number
|
||||
const XmlNode *resourceNumberNode= typeNode->getChild("resource-number");
|
||||
resourceNumber= resourceNumberNode->getAttribute("value")->getIntValue();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case rcConsumable:{
|
||||
//interval
|
||||
const XmlNode *intervalNode= typeNode->getChild("interval");
|
||||
interval= intervalNode->getAttribute("value")->getIntValue();
|
||||
case rcTileset:
|
||||
{
|
||||
//resource number
|
||||
const XmlNode *defaultAmountNode= typeNode->getChild("default-amount");
|
||||
defResPerPatch= defaultAmountNode->getAttribute("value")->getIntValue();
|
||||
|
||||
//resource number
|
||||
const XmlNode *tilesetObjectNode= typeNode->getChild("tileset-object");
|
||||
tilesetObject= tilesetObjectNode->getAttribute("value")->getIntValue();
|
||||
}
|
||||
break;
|
||||
|
||||
case rcConsumable:
|
||||
{
|
||||
//interval
|
||||
const XmlNode *intervalNode= typeNode->getChild("interval");
|
||||
interval= intervalNode->getAttribute("value")->getIntValue();
|
||||
}
|
||||
break;
|
||||
|
||||
case rcStatic:
|
||||
{
|
||||
//recoup_cost
|
||||
if(typeNode->hasChild("recoup_cost") == true)
|
||||
{
|
||||
const XmlNode *recoup_costNode= typeNode->getChild("recoup_cost");
|
||||
if(recoup_costNode != NULL)
|
||||
{
|
||||
recoup_cost= recoup_costNode->getAttribute("value")->getBoolValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(const exception &e){
|
||||
|
@ -103,7 +124,7 @@ void ResourceType::load(const string &dir, Checksum* checksum){
|
|||
}
|
||||
|
||||
|
||||
// ==================== misc ====================
|
||||
// ==================== misc ====================
|
||||
|
||||
ResourceClass ResourceType::strToRc(const string &s){
|
||||
if(s=="tech"){
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -22,7 +22,7 @@ using Shared::Graphics::Model;
|
|||
using Shared::Util::Checksum;
|
||||
|
||||
enum ResourceClass{
|
||||
rcTech,
|
||||
rcTech,
|
||||
rcTileset,
|
||||
rcStatic,
|
||||
rcConsumable
|
||||
|
@ -41,6 +41,8 @@ private:
|
|||
int resourceNumber; //used only if class==rcTech, resource number in the map
|
||||
int interval; //used only if class==rcConsumable
|
||||
int defResPerPatch; //used only if class==rcTileset || class==rcTech
|
||||
bool recoup_cost;
|
||||
|
||||
Model *model;
|
||||
|
||||
public:
|
||||
|
@ -53,6 +55,7 @@ public:
|
|||
int getInterval() const {return interval;}
|
||||
int getDefResPerPatch() const {return defResPerPatch;}
|
||||
const Model *getModel() const {return model;}
|
||||
bool getRecoup_cost() const { return recoup_cost;}
|
||||
|
||||
static ResourceClass strToRc(const string &s);
|
||||
};
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -31,7 +31,7 @@ class FactionType;
|
|||
|
||||
|
||||
// ===============================
|
||||
// class Level
|
||||
// class Level
|
||||
// ===============================
|
||||
|
||||
class Level{
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
};
|
||||
|
||||
// ===============================
|
||||
// class UnitType
|
||||
// class UnitType
|
||||
//
|
||||
/// A unit or building type
|
||||
// ===============================
|
||||
|
@ -89,9 +89,9 @@ private:
|
|||
bool light;
|
||||
Vec3f lightColor;
|
||||
bool multiSelect;
|
||||
int sight;
|
||||
int sight;
|
||||
int size; //size in cells
|
||||
int height;
|
||||
int height;
|
||||
|
||||
//cellmap
|
||||
bool *cellMap;
|
||||
|
@ -131,10 +131,10 @@ public:
|
|||
bool getProperty(Property property) const {return properties[property];}
|
||||
int getArmor() const {return armor;}
|
||||
const ArmorType *getArmorType() const {return armorType;}
|
||||
const SkillType *getSkillType(int i) const {return skillTypes[i];}
|
||||
const SkillType *getSkillType(int i) const {return skillTypes[i];}
|
||||
const CommandType *getCommandType(int i) const {return commandTypes[i];}
|
||||
const Level *getLevel(int i) const {return &levels[i];}
|
||||
int getSkillTypeCount() const {return skillTypes.size();}
|
||||
int getSkillTypeCount() const {return skillTypes.size();}
|
||||
int getCommandTypeCount() const {return commandTypes.size();}
|
||||
int getLevelCount() const {return levels.size();}
|
||||
bool getLight() const {return light;}
|
||||
|
@ -143,7 +143,7 @@ public:
|
|||
int getSight() const {return sight;}
|
||||
int getSize() const {return size;}
|
||||
int getHeight() const {return height;}
|
||||
int getStoredResourceCount() const {return storedResources.size();}
|
||||
int getStoredResourceCount() const {return storedResources.size();}
|
||||
const Resource *getStoredResource(int i) const {return &storedResources[i];}
|
||||
bool getCellMapCell(int x, int y) const {return cellMap[size*y+x];}
|
||||
bool getMeetingPoint() const {return meetingPoint;}
|
||||
|
@ -166,7 +166,7 @@ public:
|
|||
int getTotalSight(const TotalUpgrade *totalUpgrade) const;
|
||||
|
||||
//has
|
||||
bool hasCommandType(const CommandType *commandType) const;
|
||||
bool hasCommandType(const CommandType *commandType) const;
|
||||
bool hasCommandClass(CommandClass commandClass) const;
|
||||
bool hasSkillType(const SkillType *skillType) const;
|
||||
bool hasSkillClass(SkillClass skillClass) const;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<EFBFBD>o Figueroa
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <map>
|
||||
|
||||
using std::string;
|
||||
|
||||
|
@ -51,20 +52,30 @@ public:
|
|||
class Socket {
|
||||
protected:
|
||||
int sock;
|
||||
|
||||
|
||||
public:
|
||||
Socket(int sock);
|
||||
Socket();
|
||||
~Socket();
|
||||
|
||||
static bool enableDebugText;
|
||||
|
||||
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
||||
static bool hasDataToRead(std::map<int,bool> &socketTriggeredList);
|
||||
static bool hasDataToRead(int socket);
|
||||
bool hasDataToRead();
|
||||
void disconnectSocket();
|
||||
|
||||
int getSocketId() const { return sock; }
|
||||
|
||||
int getDataToRead();
|
||||
int send(const void *data, int dataSize);
|
||||
int receive(void *data, int dataSize);
|
||||
int peek(void *data, int dataSize);
|
||||
|
||||
|
||||
void setBlock(bool block);
|
||||
bool isReadable();
|
||||
bool isWritable();
|
||||
bool isWritable(bool waitOnDelayedResponse);
|
||||
bool isConnected();
|
||||
|
||||
string getHostName() const;
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// ==============================================================
|
||||
#ifndef _SHARED_PLATFORM_PLATFORMUTIL_H_
|
||||
|
@ -18,6 +18,8 @@
|
|||
#include <SDL.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "checksum.h"
|
||||
#include <utility>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
@ -25,6 +27,8 @@ using std::exception;
|
|||
|
||||
using Shared::Platform::int64;
|
||||
|
||||
using Shared::Util::Checksum;
|
||||
|
||||
namespace Shared{ namespace Platform{
|
||||
|
||||
// =====================================================
|
||||
|
@ -41,7 +45,7 @@ private:
|
|||
|
||||
public:
|
||||
void init(float fps, int maxTimes= -1);
|
||||
|
||||
|
||||
bool isTime();
|
||||
void reset();
|
||||
};
|
||||
|
@ -85,6 +89,10 @@ public:
|
|||
// =====================================================
|
||||
|
||||
void findAll(const string &path, vector<string> &results, bool cutExtension=false);
|
||||
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum);
|
||||
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap);
|
||||
void createDirectoryPaths(string Path);
|
||||
string extractDirectoryPathFromFile(string filename);
|
||||
|
||||
bool changeVideoMode(int resH, int resW, int colorBits, int refreshFrequency);
|
||||
void restoreVideoMode();
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
#include <gl.h>
|
||||
#include <glu.h>
|
||||
#include <GL\gl.h>
|
||||
#include <GL\glu.h>
|
||||
#include <glprocs.h>
|
||||
|
||||
#include <string>
|
||||
|
|
|
@ -19,12 +19,15 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#include "types.h"
|
||||
#include "checksum.h"
|
||||
#include <utility>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::exception;
|
||||
|
||||
using Shared::Platform::int64;
|
||||
using Shared::Util::Checksum;
|
||||
|
||||
namespace Shared{ namespace Platform{
|
||||
|
||||
|
@ -96,6 +99,10 @@ public:
|
|||
// =====================================================
|
||||
|
||||
void findAll(const string &path, vector<string> &results, bool cutExtension=false);
|
||||
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum);
|
||||
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap);
|
||||
void createDirectoryPaths(string Path);
|
||||
string extractDirectoryPathFromFile(string filename);
|
||||
|
||||
bool changeVideoMode(int resH, int resW, int colorBits, int refreshFrequency);
|
||||
void restoreVideoMode();
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <winsock.h>
|
||||
#include <map>
|
||||
|
||||
using std::string;
|
||||
|
||||
|
@ -51,20 +52,30 @@ private:
|
|||
protected:
|
||||
static SocketManager socketManager;
|
||||
SOCKET sock;
|
||||
|
||||
|
||||
public:
|
||||
Socket(SOCKET sock);
|
||||
Socket();
|
||||
~Socket();
|
||||
|
||||
static bool enableDebugText;
|
||||
|
||||
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
||||
static bool hasDataToRead(std::map<int,bool> &socketTriggeredList);
|
||||
static bool hasDataToRead(int socket);
|
||||
bool hasDataToRead();
|
||||
void disconnectSocket();
|
||||
|
||||
int getSocketId() const { return sock; }
|
||||
|
||||
int getDataToRead();
|
||||
int send(const void *data, int dataSize);
|
||||
int receive(void *data, int dataSize);
|
||||
int peek(void *data, int dataSize);
|
||||
|
||||
|
||||
void setBlock(bool block);
|
||||
bool isReadable();
|
||||
bool isWritable();
|
||||
bool isWritable(bool waitOnDelayedResponse);
|
||||
bool isConnected();
|
||||
|
||||
string getHostName() const;
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -32,7 +32,7 @@ private:
|
|||
int32 r;
|
||||
int32 c1;
|
||||
int32 c2;
|
||||
|
||||
|
||||
public:
|
||||
Checksum();
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -35,11 +35,11 @@ class XmlIo;
|
|||
class XmlTree;
|
||||
class XmlNode;
|
||||
class XmlAttribute;
|
||||
|
||||
|
||||
// =====================================================
|
||||
// class XmlIo
|
||||
//
|
||||
/// Wrapper for Xerces C++
|
||||
// class XmlIo
|
||||
//
|
||||
/// Wrapper for Xerces C++
|
||||
// =====================================================
|
||||
|
||||
class XmlIo{
|
||||
|
@ -72,11 +72,11 @@ private:
|
|||
public:
|
||||
XmlTree();
|
||||
~XmlTree();
|
||||
|
||||
|
||||
void init(const string &name);
|
||||
void load(const string &path);
|
||||
void save(const string &path);
|
||||
|
||||
|
||||
XmlNode *getRootNode() const {return rootNode;}
|
||||
};
|
||||
|
||||
|
@ -89,7 +89,7 @@ private:
|
|||
string name;
|
||||
string text;
|
||||
vector<XmlNode*> children;
|
||||
vector<XmlAttribute*> attributes;
|
||||
vector<XmlAttribute*> attributes;
|
||||
|
||||
private:
|
||||
XmlNode(XmlNode&);
|
||||
|
@ -109,6 +109,7 @@ public:
|
|||
XmlAttribute *getAttribute(const string &name) const;
|
||||
XmlNode *getChild(int i) const;
|
||||
XmlNode *getChild(const string &childName, int childIndex=0) const;
|
||||
bool hasChild(const string &childName) const;
|
||||
XmlNode *getParent() const;
|
||||
|
||||
|
||||
|
@ -143,9 +144,9 @@ public:
|
|||
const string &getValue() const {return value;}
|
||||
|
||||
bool getBoolValue() const;
|
||||
int getIntValue() const;
|
||||
int getIntValue() const;
|
||||
int getIntValue(int min, int max) const;
|
||||
float getFloatValue() const;
|
||||
float getFloatValue() const;
|
||||
float getFloatValue(float min, float max) const;
|
||||
const string &getRestrictedValue() const;
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//This file is part of Glest Shared Library (www.glest.org)
|
||||
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
|
||||
|
||||
//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
|
||||
//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 "socket.h"
|
||||
|
@ -28,6 +28,8 @@ using namespace Shared::Util;
|
|||
|
||||
namespace Shared{ namespace Platform{
|
||||
|
||||
bool Socket::enableDebugText = true;
|
||||
|
||||
// =====================================================
|
||||
// class Ip
|
||||
// =====================================================
|
||||
|
@ -48,7 +50,7 @@ Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned c
|
|||
|
||||
|
||||
Ip::Ip(const string& ipString){
|
||||
int offset= 0;
|
||||
int offset= 0;
|
||||
int byteIndex= 0;
|
||||
|
||||
for(byteIndex= 0; byteIndex<4; ++byteIndex){
|
||||
|
@ -71,51 +73,307 @@ Socket::Socket(int sock){
|
|||
this->sock= sock;
|
||||
}
|
||||
|
||||
Socket::Socket(){
|
||||
Socket::Socket()
|
||||
{
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(sock<0) {
|
||||
if(sock < 0)
|
||||
{
|
||||
throwException("Error creating socket");
|
||||
}
|
||||
}
|
||||
|
||||
Socket::~Socket() {
|
||||
::close(sock);
|
||||
Socket::~Socket()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
|
||||
disconnectSocket();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
}
|
||||
|
||||
void Socket::disconnectSocket()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
|
||||
if(sock > 0)
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] calling shutdown and close for socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
::shutdown(sock,2);
|
||||
::close(sock);
|
||||
sock = -1;
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
}
|
||||
|
||||
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
||||
bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
if(socketTriggeredList.size() > 0)
|
||||
{
|
||||
/* Watch stdin (fd 0) to see when it has input. */
|
||||
fd_set rfds;
|
||||
FD_ZERO(&rfds);
|
||||
|
||||
int imaxsocket = 0;
|
||||
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
|
||||
itermap != socketTriggeredList.end(); itermap++)
|
||||
{
|
||||
int socket = itermap->first;
|
||||
if(socket > 0)
|
||||
{
|
||||
FD_SET(socket, &rfds);
|
||||
imaxsocket = max(socket,imaxsocket);
|
||||
}
|
||||
}
|
||||
|
||||
if(imaxsocket > 0)
|
||||
{
|
||||
/* Wait up to 0 seconds. */
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int retval = select(imaxsocket + 1, &rfds, NULL, NULL, &tv);
|
||||
if(retval < 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d errno = %d [%s]",__FILE__,__FUNCTION__,retval,errno,strerror(errno));
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
|
||||
}
|
||||
else if(retval)
|
||||
{
|
||||
bResult = true;
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] select detected data imaxsocket = %d...\n",__FILE__,__FUNCTION__,imaxsocket);
|
||||
|
||||
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
|
||||
itermap != socketTriggeredList.end(); itermap++)
|
||||
{
|
||||
int socket = itermap->first;
|
||||
if (FD_ISSET(socket, &rfds))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s] FD_ISSET true for socket %d...\n",__FUNCTION__,socket);
|
||||
|
||||
itermap->second = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
itermap->second = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] socketTriggeredList->size() = %d\n",__FILE__,__FUNCTION__,socketTriggeredList.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
bool Socket::hasDataToRead()
|
||||
{
|
||||
return Socket::hasDataToRead(sock) ;
|
||||
}
|
||||
|
||||
bool Socket::hasDataToRead(int socket)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
if(socket > 0)
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
/* Watch stdin (fd 0) to see when it has input. */
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(socket, &rfds);
|
||||
|
||||
/* Wait up to 0 seconds. */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int retval = select(socket + 1, &rfds, NULL, NULL, &tv);
|
||||
if(retval)
|
||||
{
|
||||
if (FD_ISSET(socket, &rfds))
|
||||
{
|
||||
bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
int Socket::getDataToRead(){
|
||||
unsigned long size;
|
||||
unsigned long size = 0;
|
||||
|
||||
/* ioctl isn't posix, but the following seems to work on all modern
|
||||
* unixes */
|
||||
int err= ioctl(sock, FIONREAD, &size);
|
||||
//fd_set rfds;
|
||||
//struct timeval tv;
|
||||
//int retval;
|
||||
|
||||
if(err < 0 && errno != EAGAIN){
|
||||
throwException("Can not get data to read");
|
||||
}
|
||||
/* Watch stdin (fd 0) to see when it has input. */
|
||||
//FD_ZERO(&rfds);
|
||||
//FD_SET(sock, &rfds);
|
||||
|
||||
/* Wait up to 0 seconds. */
|
||||
//tv.tv_sec = 0;
|
||||
//tv.tv_usec = 0;
|
||||
|
||||
//retval = select(sock + 1, &rfds, NULL, NULL, &tv);
|
||||
//if(retval)
|
||||
if(sock > 0)
|
||||
{
|
||||
/* ioctl isn't posix, but the following seems to work on all modern
|
||||
* unixes */
|
||||
int err= ioctl(sock, FIONREAD, &size);
|
||||
|
||||
if(err < 0 && errno != EAGAIN)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s] ERROR PEEKING SOCKET DATA, err = %d errno = %d [%s]",__FILE__,__FUNCTION__,err,errno,strerror(errno));
|
||||
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(err == 0)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s] ioctl returned = %d, size = %ld\n",__FUNCTION__,err,size);
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int>(size);
|
||||
}
|
||||
|
||||
int Socket::send(const void *data, int dataSize) {
|
||||
ssize_t bytesSent= ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
||||
if(bytesSent<0 && errno != EAGAIN) {
|
||||
throwException("error while receiving socket data");
|
||||
ssize_t bytesSent= 0;
|
||||
if(sock > 0)
|
||||
{
|
||||
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
||||
}
|
||||
if(bytesSent < 0 && errno != EAGAIN)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s] ERROR WRITING SOCKET DATA, err = %d errno = %d [%s]",__FILE__,__FUNCTION__,bytesSent,errno,strerror(errno));
|
||||
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(bytesSent < 0 && errno == EAGAIN)
|
||||
{
|
||||
printf("In [%s::%s] #1 EAGAIN during send, trying again...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStartTimer = time(NULL);
|
||||
while((bytesSent < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||
{
|
||||
if(Socket::isWritable(true) == true)
|
||||
{
|
||||
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
||||
|
||||
printf("In [%s::%s] #2 EAGAIN during send, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesSent);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bytesSent <= 0)
|
||||
{
|
||||
int iErr = errno;
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesSent,iErr,strerror(iErr));
|
||||
printf("%s",szBuf);
|
||||
//throwException(szBuf);
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] sock = %d, bytesSent = %d\n",__FILE__,__FUNCTION__,sock,bytesSent);
|
||||
|
||||
return static_cast<int>(bytesSent);
|
||||
}
|
||||
|
||||
int Socket::receive(void *data, int dataSize) {
|
||||
ssize_t bytesReceived= recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
||||
if(bytesReceived<0 && errno != EAGAIN) {
|
||||
throwException("error while receiving socket data");
|
||||
int Socket::receive(void *data, int dataSize)
|
||||
{
|
||||
ssize_t bytesReceived = 0;
|
||||
|
||||
if(sock > 0)
|
||||
{
|
||||
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
||||
}
|
||||
if(bytesReceived < 0 && errno != EAGAIN)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesReceived,errno,strerror(errno));
|
||||
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(bytesReceived < 0 && errno == EAGAIN)
|
||||
{
|
||||
printf("In [%s::%s] #1 EAGAIN during receive, trying again...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStartTimer = time(NULL);
|
||||
while((bytesReceived < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||
{
|
||||
if(Socket::isReadable() == true)
|
||||
{
|
||||
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
||||
|
||||
printf("In [%s::%s] #2 EAGAIN during receive, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesReceived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bytesReceived <= 0)
|
||||
{
|
||||
int iErr = errno;
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesReceived,iErr,strerror(iErr));
|
||||
printf("%s",szBuf);
|
||||
//throwException(szBuf);
|
||||
}
|
||||
return static_cast<int>(bytesReceived);
|
||||
}
|
||||
|
||||
int Socket::peek(void *data, int dataSize){
|
||||
ssize_t err= recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
||||
if(err<0 && errno != EAGAIN){
|
||||
throwException("Can not receive data");
|
||||
ssize_t err = 0;
|
||||
if(sock > 0)
|
||||
{
|
||||
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
||||
}
|
||||
if(err < 0 && errno != EAGAIN)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] ERROR PEEKING SOCKET DATA error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,errno,strerror(errno));
|
||||
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(err < 0 && errno == EAGAIN)
|
||||
{
|
||||
printf("In [%s::%s] #1 EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStartTimer = time(NULL);
|
||||
while((err < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||
{
|
||||
if(Socket::isReadable() == true)
|
||||
{
|
||||
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
||||
|
||||
printf("In [%s::%s] #2 EAGAIN during peek, trying again returned: %d\n",__FILE__,__FUNCTION__,err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(err <= 0)
|
||||
{
|
||||
int iErr = errno;
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,iErr,strerror(iErr));
|
||||
printf("%s",szBuf);
|
||||
//throwException(szBuf);
|
||||
}
|
||||
|
||||
return static_cast<int>(err);
|
||||
|
@ -128,49 +386,114 @@ void Socket::setBlock(bool block){
|
|||
}
|
||||
}
|
||||
|
||||
bool Socket::isReadable(){
|
||||
bool Socket::isReadable()
|
||||
{
|
||||
if(sock <= 0) return false;
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec= 0;
|
||||
tv.tv_usec= 10;
|
||||
tv.tv_usec= 1;
|
||||
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(sock, &set);
|
||||
|
||||
int i= select(sock+1, &set, NULL, NULL, &tv);
|
||||
if(i<0){
|
||||
throwException("Error selecting socket");
|
||||
if(i < 0)
|
||||
{
|
||||
//throwException("Error selecting socket");
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
|
||||
printf("%s",szBuf);
|
||||
}
|
||||
return i==1;
|
||||
//return (i == 1 && FD_ISSET(sock, &set));
|
||||
return (i == 1);
|
||||
}
|
||||
|
||||
bool Socket::isWritable(){
|
||||
bool Socket::isWritable(bool waitOnDelayedResponse)
|
||||
{
|
||||
if(sock <= 0) return false;
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec= 0;
|
||||
tv.tv_usec= 10;
|
||||
tv.tv_usec= 1;
|
||||
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(sock, &set);
|
||||
|
||||
int i= select(sock+1, NULL, &set, NULL, &tv);
|
||||
if(i<0){
|
||||
throwException("Error selecting socket");
|
||||
}
|
||||
return i==1;
|
||||
bool result = false;
|
||||
do
|
||||
{
|
||||
int i = select(sock+1, NULL, &set, NULL, &tv);
|
||||
if(i < 0 )
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
|
||||
printf("%s",szBuf);
|
||||
waitOnDelayedResponse = false;
|
||||
|
||||
//throwException("Error selecting socket");
|
||||
}
|
||||
else if(i == 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] TIMEOUT while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
|
||||
printf("%s",szBuf);
|
||||
|
||||
if(waitOnDelayedResponse == false)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
} while(waitOnDelayedResponse == true && result == false);
|
||||
|
||||
//return (i == 1 && FD_ISSET(sock, &set));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Socket::isConnected(){
|
||||
|
||||
bool Socket::isConnected()
|
||||
{
|
||||
//if the socket is not writable then it is not conencted
|
||||
if(!isWritable()){
|
||||
if(isWritable(false) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//if the socket is readable it is connected if we can read a byte from it
|
||||
if(isReadable()){
|
||||
if(isReadable())
|
||||
{
|
||||
char tmp;
|
||||
return recv(sock, &tmp, sizeof(tmp), MSG_PEEK) > 0;
|
||||
int err = peek(&tmp, sizeof(tmp));
|
||||
return (err > 0);
|
||||
/*
|
||||
int err = recv(sock, &tmp, sizeof(tmp), MSG_PEEK);
|
||||
|
||||
if(err <= 0 && errno != EAGAIN)
|
||||
{
|
||||
int iErr = errno;
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking isconnected socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,iErr,strerror(iErr));
|
||||
printf("%s",szBuf);
|
||||
|
||||
return false;
|
||||
}
|
||||
else if(err <= 0)
|
||||
{
|
||||
int iErr = errno;
|
||||
//disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] #2 DISCONNECTED SOCKET error while peeking isconnected socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,iErr,strerror(iErr));
|
||||
printf("%s",szBuf);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//otherwise the socket is connected
|
||||
|
@ -198,9 +521,9 @@ string Socket::getIp() const{
|
|||
throw runtime_error("Error getting host ip");
|
||||
}
|
||||
|
||||
return
|
||||
intToStr(address[0]) + "." +
|
||||
intToStr(address[1]) + "." +
|
||||
return
|
||||
intToStr(address[0]) + "." +
|
||||
intToStr(address[1]) + "." +
|
||||
intToStr(address[2]) + "." +
|
||||
intToStr(address[3]);
|
||||
}
|
||||
|
@ -215,7 +538,8 @@ void Socket::throwException(const string &str){
|
|||
// class ClientSocket
|
||||
// ===============================================
|
||||
|
||||
void ClientSocket::connect(const Ip &ip, int port){
|
||||
void ClientSocket::connect(const Ip &ip, int port)
|
||||
{
|
||||
sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
|
@ -224,20 +548,23 @@ void ClientSocket::connect(const Ip &ip, int port){
|
|||
addr.sin_port= htons(port);
|
||||
|
||||
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
|
||||
if(err < 0) {
|
||||
if(err < 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"#2 Error connecting socket for IP: %s for Port: %d err = %d errno = %d [%s]",ip.getString().c_str(),port,err,errno,strerror(errno));
|
||||
sprintf(szBuf,"In [%s::%s] #2 Error connecting socket for IP: %s for Port: %d err = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,ip.getString().c_str(),port,err,errno,strerror(errno));
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
|
||||
if (errno == EINPROGRESS) {
|
||||
|
||||
if (errno == EINPROGRESS)
|
||||
{
|
||||
fd_set myset;
|
||||
struct timeval tv;
|
||||
int valopt;
|
||||
socklen_t lon;
|
||||
|
||||
fprintf(stderr, "EINPROGRESS in connect() - selecting\n");
|
||||
do {
|
||||
fprintf(stderr, "In [%s::%s] EINPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__);
|
||||
|
||||
do
|
||||
{
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
|
@ -246,41 +573,57 @@ void ClientSocket::connect(const Ip &ip, int port){
|
|||
|
||||
err = select(sock+1, NULL, &myset, NULL, &tv);
|
||||
|
||||
if (err < 0 && errno != EINTR) {
|
||||
sprintf(szBuf, "Error connecting %d - %s\n", errno, strerror(errno));
|
||||
throwException(szBuf);
|
||||
if (err < 0 && errno != EINTR)
|
||||
{
|
||||
sprintf(szBuf, "In [%s::%s] Error connecting %d - [%s]\n",__FILE__,__FUNCTION__,errno, strerror(errno));
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
else if (err > 0) {
|
||||
else if (err > 0)
|
||||
{
|
||||
// Socket selected for write
|
||||
lon = sizeof(int);
|
||||
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
|
||||
sprintf(szBuf, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
|
||||
throwException(szBuf);
|
||||
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0)
|
||||
{
|
||||
sprintf(szBuf, "In [%s::%s] Error in getsockopt() %d - [%s]\n",__FILE__,__FUNCTION__,errno, strerror(errno));
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
// Check the value returned...
|
||||
if (valopt) {
|
||||
sprintf(szBuf, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));
|
||||
throwException(szBuf);
|
||||
if (valopt)
|
||||
{
|
||||
sprintf(szBuf, "In [%s::%s] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,valopt, strerror(valopt));
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
fprintf(stderr, "Apparent recovery for connection sock = %d, err = %d, errno = %d\n",sock,err,errno);
|
||||
fprintf(stderr, "In [%s::%s] Apparent recovery for connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
||||
|
||||
break;
|
||||
}
|
||||
else {
|
||||
sprintf(szBuf, "Timeout in select() - Cancelling!\n");
|
||||
throwException(szBuf);
|
||||
else
|
||||
{
|
||||
sprintf(szBuf, "In [%s::%s] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__);
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
if(err < 0)
|
||||
{
|
||||
throwException(szBuf);
|
||||
fprintf(stderr, "In [%s::%s] Before END sock = %d, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,sock,err,errno,strerror(errno));
|
||||
//throwException(szBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "In [%s::%s] Valid recovery for connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Valid recovery for connection sock = %d, err = %d, errno = %d\n",sock,err,errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,7 +631,8 @@ void ClientSocket::connect(const Ip &ip, int port){
|
|||
// class ServerSocket
|
||||
// ===============================================
|
||||
|
||||
void ServerSocket::bind(int port){
|
||||
void ServerSocket::bind(int port)
|
||||
{
|
||||
//sockaddr structure
|
||||
sockaddr_in addr;
|
||||
addr.sin_family= AF_INET;
|
||||
|
@ -297,30 +641,45 @@ void ServerSocket::bind(int port){
|
|||
|
||||
int val = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||
|
||||
|
||||
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
|
||||
if(err < 0) {
|
||||
throwException("Error binding socket");
|
||||
if(err < 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf, "In [%s::%s] Error binding socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
||||
throwException(szBuf);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSocket::listen(int connectionQueueSize){
|
||||
void ServerSocket::listen(int connectionQueueSize)
|
||||
{
|
||||
int err= ::listen(sock, connectionQueueSize);
|
||||
if(err < 0) {
|
||||
throwException("Error listening socket");
|
||||
if(err < 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf, "In [%s::%s] Error listening socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
||||
throwException(szBuf);
|
||||
}
|
||||
}
|
||||
|
||||
Socket *ServerSocket::accept(){
|
||||
Socket *ServerSocket::accept()
|
||||
{
|
||||
int newSock= ::accept(sock, NULL, NULL);
|
||||
if(newSock < 0) {
|
||||
if(errno == EAGAIN)
|
||||
return NULL;
|
||||
if(newSock < 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
if(Socket::enableDebugText) printf(szBuf, "In [%s::%s] Error accepting socket connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,newSock,errno);
|
||||
|
||||
if(errno == EAGAIN)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
throwException(szBuf);
|
||||
|
||||
throwException("Error accepting socket connection");
|
||||
}
|
||||
return new Socket(newSock);
|
||||
}
|
||||
|
||||
|
||||
}}//end namespace
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//This file is part of Glest Shared Library (www.glest.org)
|
||||
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
|
||||
|
||||
//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
|
||||
//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 "platform_util.h"
|
||||
|
||||
|
@ -24,6 +24,10 @@
|
|||
#include "window.h"
|
||||
#include "noimpl.h"
|
||||
|
||||
#include "checksum.h"
|
||||
#include "socket.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace Shared::Util;
|
||||
using namespace std;
|
||||
|
||||
|
@ -38,7 +42,7 @@ int ScreenHeight;
|
|||
}
|
||||
|
||||
// =====================================
|
||||
// PerformanceTimer
|
||||
// PerformanceTimer
|
||||
// =====================================
|
||||
|
||||
void PerformanceTimer::init(float fps, int maxTimes){
|
||||
|
@ -67,7 +71,7 @@ void PerformanceTimer::reset(){
|
|||
}
|
||||
|
||||
// =====================================
|
||||
// Chrono
|
||||
// Chrono
|
||||
// =====================================
|
||||
|
||||
Chrono::Chrono() {
|
||||
|
@ -111,7 +115,7 @@ int64 Chrono::queryCounter(int multiplier) const {
|
|||
}
|
||||
|
||||
// =====================================
|
||||
// Misc
|
||||
// Misc
|
||||
// =====================================
|
||||
|
||||
//finds all filenames like path and stores them in resultys
|
||||
|
@ -128,7 +132,7 @@ void findAll(const string &path, vector<string> &results, bool cutExtension) {
|
|||
}
|
||||
|
||||
glob_t globbuf;
|
||||
|
||||
|
||||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
|
@ -160,6 +164,217 @@ void findAll(const string &path, vector<string> &results, bool cutExtension) {
|
|||
}
|
||||
}
|
||||
|
||||
int isdir(const char *path)
|
||||
{
|
||||
struct stat stats;
|
||||
|
||||
return stat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
|
||||
}
|
||||
|
||||
bool EndsWith(const string &str, const string& key)
|
||||
{
|
||||
size_t keylen = key.length();
|
||||
size_t strlen = str.length();
|
||||
|
||||
if(keylen <= strlen)
|
||||
return string::npos != str.rfind(key.c_str(),strlen - keylen, keylen);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//finds all filenames like path and gets their checksum of all files combined
|
||||
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum) {
|
||||
|
||||
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
|
||||
|
||||
std::string mypath = path;
|
||||
/** Stupid win32 is searching for all files without extension when *. is
|
||||
* specified as wildcard
|
||||
*/
|
||||
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
|
||||
mypath = mypath.substr(0, mypath.size() - 2);
|
||||
mypath += "*";
|
||||
}
|
||||
|
||||
glob_t globbuf;
|
||||
|
||||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
/*
|
||||
const char* begin = p;
|
||||
for( ; *p != 0; ++p) {
|
||||
// strip the path component
|
||||
if(*p == '/')
|
||||
begin = p+1;
|
||||
}
|
||||
*/
|
||||
|
||||
if(isdir(p) == 0)
|
||||
{
|
||||
bool addFile = true;
|
||||
if(filterFileExt != "")
|
||||
{
|
||||
addFile = EndsWith(p, filterFileExt);
|
||||
}
|
||||
|
||||
if(addFile)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
|
||||
|
||||
checksum.addFile(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
// Look recursively for sub-folders
|
||||
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
/*
|
||||
const char* begin = p;
|
||||
for( ; *p != 0; ++p) {
|
||||
// strip the path component
|
||||
if(*p == '/')
|
||||
begin = p+1;
|
||||
}
|
||||
*/
|
||||
|
||||
getFolderTreeContentsCheckSumRecursively(string(p) + "/*", filterFileExt, &checksum);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
return checksum.getSum();
|
||||
}
|
||||
|
||||
//finds all filenames like path and gets the checksum of each file
|
||||
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
|
||||
|
||||
vector<std::pair<string,int32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,int32> >() : *recursiveMap);
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
|
||||
|
||||
std::string mypath = path;
|
||||
/** Stupid win32 is searching for all files without extension when *. is
|
||||
* specified as wildcard
|
||||
*/
|
||||
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
|
||||
mypath = mypath.substr(0, mypath.size() - 2);
|
||||
mypath += "*";
|
||||
}
|
||||
|
||||
glob_t globbuf;
|
||||
|
||||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
/*
|
||||
const char* begin = p;
|
||||
for( ; *p != 0; ++p) {
|
||||
// strip the path component
|
||||
if(*p == '/')
|
||||
begin = p+1;
|
||||
}
|
||||
*/
|
||||
|
||||
if(isdir(p) == 0)
|
||||
{
|
||||
bool addFile = true;
|
||||
if(filterFileExt != "")
|
||||
{
|
||||
addFile = EndsWith(p, filterFileExt);
|
||||
}
|
||||
|
||||
if(addFile)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
|
||||
|
||||
Checksum checksum;
|
||||
checksum.addFile(p);
|
||||
|
||||
checksumFiles.push_back(std::pair<string,int32>(p,checksum.getSum()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
// Look recursively for sub-folders
|
||||
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
/*
|
||||
const char* begin = p;
|
||||
for( ; *p != 0; ++p) {
|
||||
// strip the path component
|
||||
if(*p == '/')
|
||||
begin = p+1;
|
||||
}
|
||||
*/
|
||||
|
||||
checksumFiles = getFolderTreeContentsCheckSumListRecursively(string(p) + "/*", filterFileExt, &checksumFiles);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
return checksumFiles;
|
||||
}
|
||||
|
||||
string extractDirectoryPathFromFile(string filename)
|
||||
{
|
||||
return filename.substr( 0, filename.rfind("/")+1 );
|
||||
}
|
||||
|
||||
void createDirectoryPaths(string Path)
|
||||
{
|
||||
char DirName[256]="";
|
||||
const char *path = Path.c_str();
|
||||
char *dirName = DirName;
|
||||
while(*path)
|
||||
{
|
||||
//if (('\\' == *path) || ('/' == *path))
|
||||
if ('/' == *path)
|
||||
{
|
||||
//if (':' != *(path-1))
|
||||
{
|
||||
mkdir(DirName, S_IRWXO);
|
||||
}
|
||||
}
|
||||
*dirName++ = *path++;
|
||||
*dirName = '\0';
|
||||
}
|
||||
mkdir(DirName, S_IRWXO);
|
||||
}
|
||||
|
||||
bool changeVideoMode(int resW, int resH, int colorBits, int ) {
|
||||
Private::shouldBeFullscreen = true;
|
||||
return true;
|
||||
|
|
|
@ -1,265 +1,480 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest Shared Library (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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 "platform_util.h"
|
||||
|
||||
#include <io.h>
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "util.h"
|
||||
#include "conversion.h"
|
||||
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace Shared::Util;
|
||||
using namespace std;
|
||||
|
||||
namespace Shared{ namespace Platform{
|
||||
|
||||
// =====================================================
|
||||
// class PerformanceTimer
|
||||
// =====================================================
|
||||
|
||||
void PerformanceTimer::init(int fps, int maxTimes){
|
||||
int64 freq;
|
||||
|
||||
if(QueryPerformanceFrequency((LARGE_INTEGER*) &freq)==0){
|
||||
throw runtime_error("Performance counters not supported");
|
||||
}
|
||||
|
||||
times= 0;
|
||||
this->maxTimes= maxTimes;
|
||||
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &lastTicks);
|
||||
|
||||
updateTicks= freq/fps;
|
||||
}
|
||||
|
||||
bool PerformanceTimer::isTime(){
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
|
||||
|
||||
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
|
||||
lastTicks+= updateTicks;
|
||||
times++;
|
||||
return true;
|
||||
}
|
||||
times= 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PerformanceTimer::reset(){
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
|
||||
lastTicks= thisTicks;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class Chrono
|
||||
// =====================================================
|
||||
|
||||
Chrono::Chrono(){
|
||||
if(!QueryPerformanceFrequency((LARGE_INTEGER*) &freq)){
|
||||
throw runtime_error("Performance counters not supported");
|
||||
}
|
||||
stopped= true;
|
||||
accumCount= 0;
|
||||
}
|
||||
|
||||
void Chrono::start(){
|
||||
stopped= false;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &startCount);
|
||||
}
|
||||
|
||||
void Chrono::stop(){
|
||||
int64 endCount;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
|
||||
accumCount+= endCount-startCount;
|
||||
stopped= true;
|
||||
}
|
||||
|
||||
int64 Chrono::getMicros() const{
|
||||
return queryCounter(1000000);
|
||||
}
|
||||
|
||||
int64 Chrono::getMillis() const{
|
||||
return queryCounter(1000);
|
||||
}
|
||||
|
||||
int64 Chrono::getSeconds() const{
|
||||
return queryCounter(1);
|
||||
}
|
||||
|
||||
int64 Chrono::queryCounter(int multiplier) const{
|
||||
if(stopped){
|
||||
return multiplier*accumCount/freq;
|
||||
}
|
||||
else{
|
||||
int64 endCount;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
|
||||
return multiplier*(accumCount+endCount-startCount)/freq;
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class PlatformExceptionHandler
|
||||
// =====================================================
|
||||
|
||||
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
|
||||
|
||||
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
|
||||
|
||||
HANDLE hFile = CreateFile(
|
||||
thisPointer->dumpFileName.c_str(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation;
|
||||
|
||||
lExceptionInformation.ThreadId= GetCurrentThreadId();
|
||||
lExceptionInformation.ExceptionPointers= pointers;
|
||||
lExceptionInformation.ClientPointers= false;
|
||||
|
||||
MiniDumpWriteDump(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
MiniDumpNormal,
|
||||
&lExceptionInformation,
|
||||
NULL,
|
||||
NULL );
|
||||
|
||||
thisPointer->handle();
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void PlatformExceptionHandler::install(string dumpFileName){
|
||||
thisPointer= this;
|
||||
this->dumpFileName= dumpFileName;
|
||||
SetUnhandledExceptionFilter(handler);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class Misc
|
||||
// =====================================================
|
||||
|
||||
//finds all filenames like path and stores them in resultys
|
||||
void findAll(const string &path, vector<string> &results, bool cutExtension){
|
||||
|
||||
int i= 0;
|
||||
struct _finddata_t fi;
|
||||
intptr_t handle;
|
||||
char *cstr;
|
||||
|
||||
results.clear();
|
||||
|
||||
cstr= new char[path.length()+1];
|
||||
strcpy(cstr, path.c_str());
|
||||
|
||||
if((handle=_findfirst(cstr,&fi))!=-1){
|
||||
do{
|
||||
if(!(strcmp(".", fi.name)==0 || strcmp("..", fi.name)==0)){
|
||||
i++;
|
||||
results.push_back(fi.name);
|
||||
}
|
||||
}
|
||||
while(_findnext(handle, &fi)==0);
|
||||
}
|
||||
else{
|
||||
throw runtime_error("Error opening files: "+ path);
|
||||
}
|
||||
|
||||
if(i==0){
|
||||
throw runtime_error("No files found: "+ path);
|
||||
}
|
||||
|
||||
if(cutExtension){
|
||||
for (int i=0; i<results.size(); ++i){
|
||||
results.at(i)=cutLastExt(results.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
delete [] cstr;
|
||||
}
|
||||
|
||||
bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
|
||||
DEVMODE devMode;
|
||||
|
||||
for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
|
||||
if (devMode.dmPelsWidth== resW &&
|
||||
devMode.dmPelsHeight== resH &&
|
||||
devMode.dmBitsPerPel== colorBits){
|
||||
|
||||
devMode.dmDisplayFrequency=refreshFrequency;
|
||||
|
||||
LONG result= ChangeDisplaySettings(&devMode, 0);
|
||||
if(result == DISP_CHANGE_SUCCESSFUL){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void restoreVideoMode(){
|
||||
int dispChangeErr= ChangeDisplaySettings(NULL, 0);
|
||||
assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
|
||||
}
|
||||
|
||||
void message(string message){
|
||||
MessageBox(NULL, message.c_str(), "Message", MB_OK);
|
||||
}
|
||||
|
||||
bool ask(string message){
|
||||
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
|
||||
}
|
||||
|
||||
void exceptionMessage(const exception &excp){
|
||||
string message, title;
|
||||
showCursor(true);
|
||||
|
||||
message+= "ERROR(S):\n\n";
|
||||
message+= excp.what();
|
||||
|
||||
title= "Error: Unhandled Exception";
|
||||
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
int getScreenW(){
|
||||
return GetSystemMetrics(SM_CXSCREEN);
|
||||
}
|
||||
|
||||
int getScreenH(){
|
||||
return GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
|
||||
void sleep(int millis){
|
||||
Sleep(millis);
|
||||
}
|
||||
|
||||
void showCursor(bool b){
|
||||
ShowCursor(b);
|
||||
}
|
||||
|
||||
bool isKeyDown(int virtualKey){
|
||||
return (GetKeyState(virtualKey) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
// ==============================================================
|
||||
// This file is part of Glest Shared Library (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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 "platform_util.h"
|
||||
|
||||
#include <io.h>
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "util.h"
|
||||
#include "conversion.h"
|
||||
|
||||
#include "leak_dumper.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <direct.h>
|
||||
|
||||
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
|
||||
|
||||
|
||||
using namespace Shared::Util;
|
||||
using namespace std;
|
||||
|
||||
namespace Shared{ namespace Platform{
|
||||
|
||||
// =====================================================
|
||||
// class PerformanceTimer
|
||||
// =====================================================
|
||||
|
||||
void PerformanceTimer::init(int fps, int maxTimes){
|
||||
int64 freq;
|
||||
|
||||
if(QueryPerformanceFrequency((LARGE_INTEGER*) &freq)==0){
|
||||
throw runtime_error("Performance counters not supported");
|
||||
}
|
||||
|
||||
times= 0;
|
||||
this->maxTimes= maxTimes;
|
||||
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &lastTicks);
|
||||
|
||||
updateTicks= freq/fps;
|
||||
}
|
||||
|
||||
bool PerformanceTimer::isTime(){
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
|
||||
|
||||
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
|
||||
lastTicks+= updateTicks;
|
||||
times++;
|
||||
return true;
|
||||
}
|
||||
times= 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PerformanceTimer::reset(){
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
|
||||
lastTicks= thisTicks;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class Chrono
|
||||
// =====================================================
|
||||
|
||||
Chrono::Chrono(){
|
||||
if(!QueryPerformanceFrequency((LARGE_INTEGER*) &freq)){
|
||||
throw runtime_error("Performance counters not supported");
|
||||
}
|
||||
stopped= true;
|
||||
accumCount= 0;
|
||||
}
|
||||
|
||||
void Chrono::start(){
|
||||
stopped= false;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &startCount);
|
||||
}
|
||||
|
||||
void Chrono::stop(){
|
||||
int64 endCount;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
|
||||
accumCount+= endCount-startCount;
|
||||
stopped= true;
|
||||
}
|
||||
|
||||
int64 Chrono::getMicros() const{
|
||||
return queryCounter(1000000);
|
||||
}
|
||||
|
||||
int64 Chrono::getMillis() const{
|
||||
return queryCounter(1000);
|
||||
}
|
||||
|
||||
int64 Chrono::getSeconds() const{
|
||||
return queryCounter(1);
|
||||
}
|
||||
|
||||
int64 Chrono::queryCounter(int multiplier) const{
|
||||
if(stopped){
|
||||
return multiplier*accumCount/freq;
|
||||
}
|
||||
else{
|
||||
int64 endCount;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
|
||||
return multiplier*(accumCount+endCount-startCount)/freq;
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class PlatformExceptionHandler
|
||||
// =====================================================
|
||||
|
||||
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
|
||||
|
||||
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
|
||||
|
||||
HANDLE hFile = CreateFile(
|
||||
thisPointer->dumpFileName.c_str(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation;
|
||||
|
||||
lExceptionInformation.ThreadId= GetCurrentThreadId();
|
||||
lExceptionInformation.ExceptionPointers= pointers;
|
||||
lExceptionInformation.ClientPointers= false;
|
||||
|
||||
MiniDumpWriteDump(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
MiniDumpNormal,
|
||||
&lExceptionInformation,
|
||||
NULL,
|
||||
NULL );
|
||||
|
||||
thisPointer->handle();
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void PlatformExceptionHandler::install(string dumpFileName){
|
||||
thisPointer= this;
|
||||
this->dumpFileName= dumpFileName;
|
||||
SetUnhandledExceptionFilter(handler);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class Misc
|
||||
// =====================================================
|
||||
|
||||
//finds all filenames like path and stores them in resultys
|
||||
void findAll(const string &path, vector<string> &results, bool cutExtension){
|
||||
|
||||
int i= 0;
|
||||
struct _finddata_t fi;
|
||||
intptr_t handle;
|
||||
char *cstr;
|
||||
|
||||
results.clear();
|
||||
|
||||
cstr= new char[path.length()+1];
|
||||
strcpy(cstr, path.c_str());
|
||||
|
||||
if((handle=_findfirst(cstr,&fi))!=-1){
|
||||
do{
|
||||
if(!(strcmp(".", fi.name)==0 || strcmp("..", fi.name)==0)){
|
||||
i++;
|
||||
results.push_back(fi.name);
|
||||
}
|
||||
}
|
||||
while(_findnext(handle, &fi)==0);
|
||||
}
|
||||
else{
|
||||
throw runtime_error("Error opening files: "+ path);
|
||||
}
|
||||
|
||||
if(i==0){
|
||||
throw runtime_error("No files found: "+ path);
|
||||
}
|
||||
|
||||
if(cutExtension){
|
||||
for (int i=0; i<results.size(); ++i){
|
||||
results.at(i)=cutLastExt(results.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
delete [] cstr;
|
||||
}
|
||||
|
||||
int isdir(const char *path)
|
||||
{
|
||||
struct stat stats;
|
||||
|
||||
return stat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
|
||||
}
|
||||
|
||||
bool EndsWith(const string &str, const string& key)
|
||||
{
|
||||
size_t keylen = key.length();
|
||||
size_t strlen = str.length();
|
||||
|
||||
if(keylen <= strlen)
|
||||
return string::npos != str.rfind(key.c_str(),strlen - keylen, keylen);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//finds all filenames like path and gets their checksum of all files combined
|
||||
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum) {
|
||||
|
||||
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
|
||||
|
||||
/* MV - PORT THIS to win32
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
|
||||
|
||||
std::string mypath = path;
|
||||
// Stupid win32 is searching for all files without extension when *. is specified as wildcard
|
||||
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
|
||||
mypath = mypath.substr(0, mypath.size() - 2);
|
||||
mypath += "*";
|
||||
}
|
||||
|
||||
glob_t globbuf;
|
||||
|
||||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
//
|
||||
//const char* begin = p;
|
||||
//for( ; *p != 0; ++p) {
|
||||
// // strip the path component
|
||||
// if(*p == '/')
|
||||
// begin = p+1;
|
||||
//}
|
||||
|
||||
|
||||
if(isdir(p) == 0)
|
||||
{
|
||||
bool addFile = true;
|
||||
if(filterFileExt != "")
|
||||
{
|
||||
addFile = EndsWith(p, filterFileExt);
|
||||
}
|
||||
|
||||
if(addFile)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
|
||||
|
||||
checksum.addFile(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
// Look recursively for sub-folders
|
||||
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
//
|
||||
//const char* begin = p;
|
||||
//for( ; *p != 0; ++p) {
|
||||
// strip the path component
|
||||
// if(*p == '/')
|
||||
// begin = p+1;
|
||||
//}
|
||||
|
||||
getFolderTreeContentsCheckSumRecursively(string(p) + "/*", filterFileExt, &checksum);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
*/
|
||||
return checksum.getSum();
|
||||
}
|
||||
|
||||
//finds all filenames like path and gets the checksum of each file
|
||||
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
|
||||
|
||||
vector<std::pair<string,int32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,int32> >() : *recursiveMap);
|
||||
|
||||
/* MV - PORT THIS to win32
|
||||
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
|
||||
|
||||
std::string mypath = path;
|
||||
// Stupid win32 is searching for all files without extension when *. is specified as wildcard
|
||||
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
|
||||
mypath = mypath.substr(0, mypath.size() - 2);
|
||||
mypath += "*";
|
||||
}
|
||||
|
||||
glob_t globbuf;
|
||||
|
||||
int res = glob(mypath.c_str(), 0, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
//
|
||||
//const char* begin = p;
|
||||
//for( ; *p != 0; ++p) {
|
||||
// strip the path component
|
||||
// if(*p == '/')
|
||||
// begin = p+1;
|
||||
//}
|
||||
|
||||
|
||||
if(isdir(p) == 0)
|
||||
{
|
||||
bool addFile = true;
|
||||
if(filterFileExt != "")
|
||||
{
|
||||
addFile = EndsWith(p, filterFileExt);
|
||||
}
|
||||
|
||||
if(addFile)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
|
||||
|
||||
Checksum checksum;
|
||||
checksum.addFile(p);
|
||||
|
||||
checksumFiles.push_back(std::pair<string,int32>(p,checksum.getSum()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
|
||||
// Look recursively for sub-folders
|
||||
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
|
||||
if(res < 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
|
||||
throw runtime_error(msg.str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
|
||||
const char* p = globbuf.gl_pathv[i];
|
||||
//
|
||||
//const char* begin = p;
|
||||
//for( ; *p != 0; ++p) {
|
||||
// strip the path component
|
||||
// if(*p == '/')
|
||||
// begin = p+1;
|
||||
//}
|
||||
|
||||
checksumFiles = getFolderTreeContentsCheckSumListRecursively(string(p) + "/*", filterFileExt, &checksumFiles);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
*/
|
||||
return checksumFiles;
|
||||
}
|
||||
|
||||
string extractDirectoryPathFromFile(string filename)
|
||||
{
|
||||
return filename.substr( 0, filename.rfind("/")+1 );
|
||||
}
|
||||
|
||||
void createDirectoryPaths(string Path)
|
||||
{
|
||||
char DirName[256]="";
|
||||
const char *path = Path.c_str();
|
||||
char *dirName = DirName;
|
||||
while(*path)
|
||||
{
|
||||
//if (('\\' == *path) || ('/' == *path))
|
||||
if ('/' == *path)
|
||||
{
|
||||
//if (':' != *(path-1))
|
||||
{
|
||||
_mkdir(DirName);
|
||||
}
|
||||
}
|
||||
*dirName++ = *path++;
|
||||
*dirName = '\0';
|
||||
}
|
||||
_mkdir(DirName);
|
||||
}
|
||||
|
||||
bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
|
||||
DEVMODE devMode;
|
||||
|
||||
for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
|
||||
if (devMode.dmPelsWidth== resW &&
|
||||
devMode.dmPelsHeight== resH &&
|
||||
devMode.dmBitsPerPel== colorBits){
|
||||
|
||||
devMode.dmDisplayFrequency=refreshFrequency;
|
||||
|
||||
LONG result= ChangeDisplaySettings(&devMode, 0);
|
||||
if(result == DISP_CHANGE_SUCCESSFUL){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void restoreVideoMode(){
|
||||
int dispChangeErr= ChangeDisplaySettings(NULL, 0);
|
||||
assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
|
||||
}
|
||||
|
||||
void message(string message){
|
||||
MessageBox(NULL, message.c_str(), "Message", MB_OK);
|
||||
}
|
||||
|
||||
bool ask(string message){
|
||||
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
|
||||
}
|
||||
|
||||
void exceptionMessage(const exception &excp){
|
||||
string message, title;
|
||||
showCursor(true);
|
||||
|
||||
message+= "ERROR(S):\n\n";
|
||||
message+= excp.what();
|
||||
|
||||
title= "Error: Unhandled Exception";
|
||||
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
int getScreenW(){
|
||||
return GetSystemMetrics(SM_CXSCREEN);
|
||||
}
|
||||
|
||||
int getScreenH(){
|
||||
return GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
|
||||
void sleep(int millis){
|
||||
Sleep(millis);
|
||||
}
|
||||
|
||||
void showCursor(bool b){
|
||||
ShowCursor(b);
|
||||
}
|
||||
|
||||
bool isKeyDown(int virtualKey){
|
||||
return (GetKeyState(virtualKey) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2007 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -16,12 +16,17 @@
|
|||
#include "conversion.h"
|
||||
|
||||
#include "leak_dumper.h"
|
||||
#include <time.h>
|
||||
|
||||
#define socklen_t int
|
||||
|
||||
using namespace std;
|
||||
using namespace Shared::Util;
|
||||
|
||||
namespace Shared{ namespace Platform{
|
||||
|
||||
bool Socket::enableDebugText = false;
|
||||
|
||||
// =====================================================
|
||||
// class Ip
|
||||
// =====================================================
|
||||
|
@ -42,7 +47,7 @@ Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned c
|
|||
|
||||
|
||||
Ip::Ip(const string& ipString){
|
||||
int offset= 0;
|
||||
int offset= 0;
|
||||
int byteIndex= 0;
|
||||
|
||||
for(byteIndex= 0; byteIndex<4; ++byteIndex){
|
||||
|
@ -64,7 +69,7 @@ string Ip::getString() const{
|
|||
Socket::SocketManager Socket::socketManager;
|
||||
|
||||
Socket::SocketManager::SocketManager(){
|
||||
WSADATA wsaData;
|
||||
WSADATA wsaData;
|
||||
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||
WSAStartup(wVersionRequested, &wsaData);
|
||||
//dont throw exceptions here, this is a static initializacion
|
||||
|
@ -85,59 +90,300 @@ Socket::Socket(){
|
|||
}
|
||||
}
|
||||
|
||||
Socket::~Socket(){
|
||||
int err= closesocket(sock);
|
||||
if(err==INVALID_SOCKET){
|
||||
throwException("Error closing socket");
|
||||
}
|
||||
Socket::~Socket()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
|
||||
disconnectSocket();
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
}
|
||||
|
||||
void Socket::disconnectSocket()
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
|
||||
if(sock > 0)
|
||||
{
|
||||
::shutdown(sock,2);
|
||||
::closesocket(sock);
|
||||
sock = -1;
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||
}
|
||||
|
||||
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
||||
bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
if(socketTriggeredList.size() > 0)
|
||||
{
|
||||
/* Watch stdin (fd 0) to see when it has input. */
|
||||
fd_set rfds;
|
||||
FD_ZERO(&rfds);
|
||||
|
||||
int imaxsocket = 0;
|
||||
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
|
||||
itermap != socketTriggeredList.end(); itermap++)
|
||||
{
|
||||
int socket = itermap->first;
|
||||
if(socket > 0)
|
||||
{
|
||||
FD_SET(socket, &rfds);
|
||||
imaxsocket = max(socket,imaxsocket);
|
||||
}
|
||||
}
|
||||
|
||||
if(imaxsocket > 0)
|
||||
{
|
||||
/* Wait up to 0 seconds. */
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int retval = select(imaxsocket + 1, &rfds, NULL, NULL, &tv);
|
||||
if(retval < 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d WSAGetLastError() = %d",__FILE__,__FUNCTION__,retval,WSAGetLastError());
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
|
||||
}
|
||||
else if(retval)
|
||||
{
|
||||
bResult = true;
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] select detected data imaxsocket = %d...\n",__FILE__,__FUNCTION__,imaxsocket);
|
||||
|
||||
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
|
||||
itermap != socketTriggeredList.end(); itermap++)
|
||||
{
|
||||
int socket = itermap->first;
|
||||
if (FD_ISSET(socket, &rfds))
|
||||
{
|
||||
if(Socket::enableDebugText) printf("In [%s] FD_ISSET true for socket %d...\n",__FUNCTION__,socket);
|
||||
|
||||
itermap->second = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
itermap->second = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] socketTriggeredList->size() = %d\n",__FILE__,__FUNCTION__,socketTriggeredList.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
bool Socket::hasDataToRead()
|
||||
{
|
||||
return Socket::hasDataToRead(sock) ;
|
||||
}
|
||||
|
||||
bool Socket::hasDataToRead(int socket)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
if(socket > 0)
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
/* Watch stdin (fd 0) to see when it has input. */
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(socket, &rfds);
|
||||
|
||||
/* Wait up to 0 seconds. */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int retval = select(socket + 1, &rfds, NULL, NULL, &tv);
|
||||
if(retval)
|
||||
{
|
||||
if (FD_ISSET(socket, &rfds))
|
||||
{
|
||||
bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
int Socket::getDataToRead(){
|
||||
u_long size;
|
||||
|
||||
int err= ioctlsocket(sock, FIONREAD, &size);
|
||||
unsigned long size = 0;
|
||||
|
||||
if(err==SOCKET_ERROR){
|
||||
if(WSAGetLastError()!=WSAEWOULDBLOCK){
|
||||
throwException("Can not get data to read");
|
||||
}
|
||||
}
|
||||
//fd_set rfds;
|
||||
//struct timeval tv;
|
||||
//int retval;
|
||||
|
||||
/* Watch stdin (fd 0) to see when it has input. */
|
||||
//FD_ZERO(&rfds);
|
||||
//FD_SET(sock, &rfds);
|
||||
|
||||
/* Wait up to 0 seconds. */
|
||||
//tv.tv_sec = 0;
|
||||
//tv.tv_usec = 0;
|
||||
|
||||
//retval = select(sock + 1, &rfds, NULL, NULL, &tv);
|
||||
//if(retval)
|
||||
if(sock > 0)
|
||||
{
|
||||
/* ioctl isn't posix, but the following seems to work on all modern
|
||||
* unixes */
|
||||
int err= ioctlsocket(sock, FIONREAD, &size);
|
||||
|
||||
if(err < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s] ERROR PEEKING SOCKET DATA, err = %d WSAGetLastError() = %d",__FILE__,__FUNCTION__,err,WSAGetLastError());
|
||||
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(err == 0)
|
||||
{
|
||||
//if(Socket::enableDebugText) printf("In [%s] ioctl returned = %d, size = %ld\n",__FUNCTION__,err,size);
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int>(size);
|
||||
}
|
||||
|
||||
int Socket::send(const void *data, int dataSize){
|
||||
int err= ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
||||
if(err==SOCKET_ERROR){
|
||||
if(WSAGetLastError()!=WSAEWOULDBLOCK){
|
||||
throwException("Can not send data");
|
||||
}
|
||||
int Socket::send(const void *data, int dataSize) {
|
||||
int bytesSent= 0;
|
||||
if(sock > 0)
|
||||
{
|
||||
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
||||
}
|
||||
return err;
|
||||
if(bytesSent < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"In [%s::%s] ERROR WRITING SOCKET DATA, err = %d WSAGetLastError() = %d",__FILE__,__FUNCTION__,bytesSent,WSAGetLastError());
|
||||
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(bytesSent < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
{
|
||||
printf("In [%s::%s] #1 WSAEWOULDBLOCK during send, trying again...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStartTimer = time(NULL);
|
||||
while((bytesSent < 0 && WSAGetLastError() == WSAEWOULDBLOCK) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||
{
|
||||
if(Socket::isWritable(true) == true)
|
||||
{
|
||||
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
||||
|
||||
printf("In [%s::%s] #2 WSAEWOULDBLOCK during send, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesSent);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bytesSent <= 0)
|
||||
{
|
||||
int iErr = WSAGetLastError();
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,bytesSent,iErr);
|
||||
printf("%s",szBuf);
|
||||
//throwException(szBuf);
|
||||
}
|
||||
|
||||
if(Socket::enableDebugText) printf("In [%s::%s] sock = %d, bytesSent = %d\n",__FILE__,__FUNCTION__,sock,bytesSent);
|
||||
|
||||
return static_cast<int>(bytesSent);
|
||||
}
|
||||
|
||||
int Socket::receive(void *data, int dataSize){
|
||||
int err= recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
||||
int Socket::receive(void *data, int dataSize)
|
||||
{
|
||||
int bytesReceived = 0;
|
||||
|
||||
if(err==SOCKET_ERROR){
|
||||
if(WSAGetLastError()!=WSAEWOULDBLOCK){
|
||||
throwException("Can not receive data");
|
||||
}
|
||||
if(sock > 0)
|
||||
{
|
||||
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
||||
}
|
||||
if(bytesReceived < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,bytesReceived,WSAGetLastError());
|
||||
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(bytesReceived < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
{
|
||||
printf("In [%s::%s] #1 WSAEWOULDBLOCK during receive, trying again...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStartTimer = time(NULL);
|
||||
while((bytesReceived < 0 && WSAGetLastError() == WSAEWOULDBLOCK) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||
{
|
||||
if(Socket::isReadable() == true)
|
||||
{
|
||||
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
||||
|
||||
printf("In [%s::%s] #2 WSAEWOULDBLOCK during receive, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesReceived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
if(bytesReceived <= 0)
|
||||
{
|
||||
int iErr = WSAGetLastError();
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,bytesReceived,iErr);
|
||||
printf("%s",szBuf);
|
||||
//throwException(szBuf);
|
||||
}
|
||||
return static_cast<int>(bytesReceived);
|
||||
}
|
||||
|
||||
int Socket::peek(void *data, int dataSize){
|
||||
int err= recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
||||
int err = 0;
|
||||
if(sock > 0)
|
||||
{
|
||||
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
||||
}
|
||||
if(err < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] ERROR PEEKING SOCKET DATA error while sending socket data, bytesSent = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,err,WSAGetLastError());
|
||||
|
||||
if(err==SOCKET_ERROR){
|
||||
if(WSAGetLastError()!=WSAEWOULDBLOCK){
|
||||
throwException("Can not receive data");
|
||||
}
|
||||
throwException(szBuf);
|
||||
}
|
||||
else if(err < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
{
|
||||
printf("In [%s::%s] #1 WSAEWOULDBLOCK during peek, trying again...\n",__FILE__,__FUNCTION__);
|
||||
|
||||
time_t tStartTimer = time(NULL);
|
||||
while((err < 0 && WSAGetLastError() == WSAEWOULDBLOCK) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||
{
|
||||
if(Socket::isReadable() == true)
|
||||
{
|
||||
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
||||
|
||||
printf("In [%s::%s] #2 WSAEWOULDBLOCK during peek, trying again returned: %d\n",__FILE__,__FUNCTION__,err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
if(err <= 0)
|
||||
{
|
||||
int iErr = WSAGetLastError();
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking socket data, err = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,err,iErr);
|
||||
printf("%s",szBuf);
|
||||
//throwException(szBuf);
|
||||
}
|
||||
|
||||
return static_cast<int>(err);
|
||||
}
|
||||
|
||||
void Socket::setBlock(bool block){
|
||||
|
@ -149,49 +395,101 @@ void Socket::setBlock(bool block){
|
|||
}
|
||||
}
|
||||
|
||||
bool Socket::isReadable(){
|
||||
bool Socket::isReadable()
|
||||
{
|
||||
if(sock <= 0) return false;
|
||||
|
||||
TIMEVAL tv;
|
||||
tv.tv_sec= 0;
|
||||
tv.tv_usec= 10;
|
||||
tv.tv_usec= 1;
|
||||
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(sock, &set);
|
||||
|
||||
int i= select(0, &set, NULL, NULL, &tv);
|
||||
if(i==SOCKET_ERROR){
|
||||
throwException("Error selecting socket");
|
||||
}
|
||||
return i==1;
|
||||
int i= select(sock+1, &set, NULL, NULL, &tv);
|
||||
if(i==SOCKET_ERROR)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d\n",__FILE__,__FUNCTION__,i,WSAGetLastError());
|
||||
printf("%s",szBuf);
|
||||
}
|
||||
//return (i == 1 && FD_ISSET(sock, &set));
|
||||
return (i == 1);
|
||||
}
|
||||
|
||||
bool Socket::isWritable(){
|
||||
bool Socket::isWritable(bool waitOnDelayedResponse)
|
||||
{
|
||||
if(sock <= 0) return false;
|
||||
|
||||
TIMEVAL tv;
|
||||
tv.tv_sec= 0;
|
||||
tv.tv_usec= 10;
|
||||
tv.tv_usec= 1;
|
||||
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(sock, &set);
|
||||
|
||||
int i= select(0, NULL, &set, NULL, &tv);
|
||||
if(i==SOCKET_ERROR){
|
||||
throwException("Error selecting socket");
|
||||
}
|
||||
return i==1;
|
||||
bool result = false;
|
||||
do
|
||||
{
|
||||
int i= select(sock+1, NULL, &set, NULL, &tv);
|
||||
if(i==SOCKET_ERROR)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d\n",__FILE__,__FUNCTION__,i,WSAGetLastError());
|
||||
printf("%s",szBuf);
|
||||
waitOnDelayedResponse = false;
|
||||
}
|
||||
else if(i == 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] TIMEOUT while selecting socket data, err = %d, errno = %d\n",__FILE__,__FUNCTION__,i,WSAGetLastError());
|
||||
printf("%s",szBuf);
|
||||
|
||||
if(waitOnDelayedResponse == false)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
} while(waitOnDelayedResponse == true && result == false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Socket::isConnected(){
|
||||
|
||||
//if the socket is not writable then it is not conencted
|
||||
if(!isWritable()){
|
||||
if(isWritable(false) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//if the socket is readable it is connected if we can read a byte from it
|
||||
if(isReadable()){
|
||||
char tmp;
|
||||
return recv(sock, &tmp, sizeof(tmp), MSG_PEEK) > 0;
|
||||
if(isReadable())
|
||||
{
|
||||
char tmp;
|
||||
int err = peek(&tmp, sizeof(tmp));
|
||||
return (err > 0);
|
||||
/*
|
||||
int err = recv(sock, &tmp, sizeof(tmp), MSG_PEEK);
|
||||
|
||||
if(err <= 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
int iErr = WSAGetLastError();
|
||||
disconnectSocket();
|
||||
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking isconnected socket data, err = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,err,iErr);
|
||||
printf("%s",szBuf);
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//otherwise the socket is connected
|
||||
|
@ -220,9 +518,9 @@ string Socket::getIp() const{
|
|||
throwException("Error getting host ip");
|
||||
}
|
||||
|
||||
return
|
||||
intToStr(address[0]) + "." +
|
||||
intToStr(address[1]) + "." +
|
||||
return
|
||||
intToStr(address[0]) + "." +
|
||||
intToStr(address[1]) + "." +
|
||||
intToStr(address[2]) + "." +
|
||||
intToStr(address[3]);
|
||||
}
|
||||
|
@ -235,20 +533,86 @@ void Socket::throwException(const string &str){
|
|||
// class ClientSocket
|
||||
// =====================================================
|
||||
|
||||
void ClientSocket::connect(const Ip &ip, int port){
|
||||
void ClientSocket::connect(const Ip &ip, int port)
|
||||
{
|
||||
sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
addr.sin_family= AF_INET;
|
||||
addr.sin_addr.s_addr= inet_addr(ip.getString().c_str());
|
||||
addr.sin_port= htons(port);
|
||||
|
||||
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
|
||||
if(err==SOCKET_ERROR){
|
||||
int lastError= WSAGetLastError();
|
||||
if(err < 0)
|
||||
{
|
||||
char szBuf[1024]="";
|
||||
sprintf(szBuf,"#2 Error connecting socket for IP: %s for Port: %d err = %d WSAGetLastError() = %d",ip.getString().c_str(),port,err,WSAGetLastError());
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
|
||||
if(lastError!=WSAEWOULDBLOCK && lastError!=WSAEALREADY){
|
||||
throwException("Can not connect");
|
||||
}
|
||||
if (WSAGetLastError() == WSAEINPROGRESS) {
|
||||
|
||||
fd_set myset;
|
||||
struct timeval tv;
|
||||
int valopt;
|
||||
socklen_t lon;
|
||||
|
||||
fprintf(stderr, "EINPROGRESS in connect() - selecting\n");
|
||||
do {
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&myset);
|
||||
FD_SET(sock, &myset);
|
||||
|
||||
err = select(sock+1, NULL, &myset, NULL, &tv);
|
||||
|
||||
if (err < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
sprintf(szBuf, "Error connecting %d\n", WSAGetLastError());
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
else if (err > 0) {
|
||||
// Socket selected for write
|
||||
lon = sizeof(int);
|
||||
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)(&valopt), &lon) < 0)
|
||||
{
|
||||
sprintf(szBuf, "Error in getsockopt() %d\n", WSAGetLastError());
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
// Check the value returned...
|
||||
if (valopt)
|
||||
{
|
||||
sprintf(szBuf, "Error in delayed connection() %d\n", valopt);
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Apparent recovery for connection sock = %d, err = %d, WSAGetLastError() = %d\n",sock,err,WSAGetLastError());
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(szBuf, "Timeout in select() - Cancelling!\n");
|
||||
//throwException(szBuf);
|
||||
fprintf(stderr, "%s", szBuf);
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
if(err < 0)
|
||||
{
|
||||
fprintf(stderr, "In [%s::%s] Before END sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,WSAGetLastError());
|
||||
//throwException(szBuf);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Valid recovery for connection sock = %d, err = %d, WSAGetLastError() = %d\n",sock,err,WSAGetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +626,7 @@ void ServerSocket::bind(int port){
|
|||
addr.sin_family= AF_INET;
|
||||
addr.sin_addr.s_addr= INADDR_ANY;
|
||||
addr.sin_port= htons(port);
|
||||
|
||||
|
||||
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
|
||||
if(err==SOCKET_ERROR){
|
||||
throwException("Error binding socket");
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -27,14 +27,14 @@ namespace Shared{ namespace Util{
|
|||
|
||||
Checksum::Checksum(){
|
||||
sum= 0;
|
||||
r= 55665;
|
||||
c1= 52845;
|
||||
r= 55665;
|
||||
c1= 52845;
|
||||
c2= 22719;
|
||||
}
|
||||
|
||||
void Checksum::addByte(int8 value){
|
||||
int32 cipher= (value ^ (r >> 8));
|
||||
|
||||
|
||||
r= (cipher + r) * c1 + c2;
|
||||
sum+= cipher;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ void Checksum::addString(const string &value){
|
|||
}
|
||||
|
||||
void Checksum::addFile(const string &path){
|
||||
|
||||
|
||||
FILE* file= fopen(path.c_str(), "rb");
|
||||
|
||||
if(file!=NULL){
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2001-2008 Martiñ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
|
||||
// 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -61,7 +61,7 @@ XmlIo::XmlIo(){
|
|||
}
|
||||
catch(const XMLException&){
|
||||
throw runtime_error("Error initializing XML system");
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
XMLCh str[strSize];
|
||||
|
@ -84,7 +84,7 @@ XmlIo::~XmlIo(){
|
|||
}
|
||||
|
||||
XmlNode *XmlIo::load(const string &path){
|
||||
|
||||
|
||||
try{
|
||||
ErrorHandler errorHandler;
|
||||
#if XERCES_VERSION_MAJOR < 3
|
||||
|
@ -99,7 +99,7 @@ XmlNode *XmlIo::load(const string &path){
|
|||
config->setParameter(XMLUni::fgDOMValidate, true);
|
||||
#endif
|
||||
DOMDocument *document= parser->parseURI(path.c_str());
|
||||
|
||||
|
||||
if(document==NULL){
|
||||
throw runtime_error("Can not parse URL: " + path);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ XmlNode *XmlIo::load(const string &path){
|
|||
}
|
||||
catch(const DOMException &e){
|
||||
throw runtime_error("Exception while loading: " + path + ": " + XMLString::transcode(e.msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XmlIo::save(const string &path, const XmlNode *node){
|
||||
|
@ -144,7 +144,7 @@ void XmlIo::save(const string &path, const XmlNode *node){
|
|||
}
|
||||
catch(const DOMException &e){
|
||||
throw runtime_error("Exception while saving: " + path + ": " + XMLString::transcode(e.msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
// =====================================================
|
||||
// class XmlTree
|
||||
|
@ -188,7 +188,7 @@ XmlNode::XmlNode(DOMNode *node){
|
|||
|
||||
//check children
|
||||
for(int i=0; i<node->getChildNodes()->getLength(); ++i){
|
||||
DOMNode *currentNode= node->getChildNodes()->item(i);
|
||||
DOMNode *currentNode= node->getChildNodes()->item(i);
|
||||
if(currentNode->getNodeType()==DOMNode::ELEMENT_NODE){
|
||||
XmlNode *xmlNode= new XmlNode(currentNode);
|
||||
children.push_back(xmlNode);
|
||||
|
@ -234,7 +234,7 @@ XmlAttribute *XmlNode::getAttribute(int i) const{
|
|||
}
|
||||
return attributes[i];
|
||||
}
|
||||
|
||||
|
||||
XmlAttribute *XmlNode::getAttribute(const string &name) const{
|
||||
for(int i=0; i<attributes.size(); ++i){
|
||||
if(attributes[i]->getName()==name){
|
||||
|
@ -269,6 +269,20 @@ XmlNode *XmlNode::getChild(const string &childName, int i) const{
|
|||
throw runtime_error("Node \""+getName()+"\" doesn't have "+intToStr(i+1)+" children named \""+childName+"\"\n\nTree: "+getTreeString());
|
||||
}
|
||||
|
||||
bool XmlNode::hasChild(const string &childName) const
|
||||
{
|
||||
int count= 0;
|
||||
for(int j = 0; j < children.size(); ++j)
|
||||
{
|
||||
if(children[j]->getName()==childName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
XmlNode *XmlNode::addChild(const string &name){
|
||||
XmlNode *node= new XmlNode(name);
|
||||
children.push_back(node);
|
||||
|
@ -290,10 +304,10 @@ DOMElement *XmlNode::buildElement(DOMDocument *document) const{
|
|||
for(int i=0; i<attributes.size(); ++i){
|
||||
XMLString::transcode(attributes[i]->getName().c_str(), str, strSize-1);
|
||||
DOMAttr *attr= document->createAttribute(str);
|
||||
|
||||
|
||||
XMLString::transcode(attributes[i]->getValue().c_str(), str, strSize-1);
|
||||
attr->setValue(str);
|
||||
|
||||
|
||||
node->setAttributeNode(attr);
|
||||
}
|
||||
|
||||
|
@ -387,7 +401,7 @@ const string &XmlAttribute::getRestrictedValue() const
|
|||
"\"\nFor portability reasons the only allowed characters in this field are: " + allowedCharacters);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue