diff --git a/binaries/data/mods/public/gui/common/setup.xml b/binaries/data/mods/public/gui/common/setup.xml
index ba9228ec6d..653a468b37 100644
--- a/binaries/data/mods/public/gui/common/setup.xml
+++ b/binaries/data/mods/public/gui/common/setup.xml
@@ -170,6 +170,8 @@
191 191 2
159 98 24
+ 0 0 0 0
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js b/binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js
new file mode 100644
index 0000000000..fe88a00cef
--- /dev/null
+++ b/binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js
@@ -0,0 +1,69 @@
+var g_IsConnecting = false;
+var g_GameType; // "server" or "client"
+
+function init()
+{
+}
+
+function startConnectionStatus(type)
+{
+ g_GameType = type;
+ g_IsConnecting = true;
+ getGUIObjectByName("connectionStatus").caption = "Connecting to server...";
+}
+
+function onTick()
+{
+ if (!g_IsConnecting)
+ return;
+
+ while (true)
+ {
+ var message = Engine.PollNetworkClient();
+ if (!message)
+ break;
+
+ warn("Net message: "+uneval(message));
+
+ switch (message.type)
+ {
+ case "netstatus":
+ switch (message.status)
+ {
+ case "connected":
+ getGUIObjectByName("connectionStatus").caption = "Registering with server...";
+ break;
+ case "authenticated":
+ Engine.PopGuiPage();
+ Engine.PushGuiPage("page_gamesetup.xml", { "type": g_GameType });
+ return; // don't process any more messages
+ default:
+ error("Unrecognised netstatus type "+message.status);
+ break;
+ }
+ break;
+ default:
+ error("Unrecognised net message type "+message.type);
+ break;
+ }
+ }
+}
+
+function switchSetupPage(oldpage, newpage)
+{
+ getGUIObjectByName(oldpage).hidden = true;
+ getGUIObjectByName(newpage).hidden = false;
+}
+
+function startHost(playername, servername)
+{
+ Engine.StartNetworkHost(playername);
+ startConnectionStatus("server");
+ // TODO: ought to do something(?) with servername
+}
+
+function startJoin(playername, ip)
+{
+ Engine.StartNetworkJoin(playername, ip);
+ startConnectionStatus("client");
+}
diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml b/binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml
new file mode 100644
index 0000000000..179ba2f494
--- /dev/null
+++ b/binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ onTick();
+
+
+
+ Multiplayer
+
+
+
+
+
+
+
+
+
+ Please select whether you want to join a game or host your own game.
+
+
+
+ Game Mode:
+
+
+
+ Join Game
+
+
+
+
+ Host Game
+
+
+
+
+
+
+
+
+ Setting up your server.
+
+
+
+ Player name:
+
+
+
+
+
+
+
+ Server name:
+
+
+
+
+
+
+
+ Continue
+
+
+
+
+ Back
+
+
+
+
+
+
+
+
+ Joining an existing game.
+
+
+
+ Player name:
+
+
+
+
+
+
+
+ Server Hostname or IP:
+
+
+
+ 127.0.0.1
+
+
+
+ Continue
+
+
+
+
+ Back
+
+
+
+
+
+
+
+ [Connection status]
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/gui/gamesetup/setup.xml b/binaries/data/mods/public/gui/gamesetup/setup.xml
new file mode 100644
index 0000000000..a68be9c9bc
--- /dev/null
+++ b/binaries/data/mods/public/gui/gamesetup/setup.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/binaries/data/mods/public/gui/gamesetup/sprites.xml b/binaries/data/mods/public/gui/gamesetup/sprites.xml
new file mode 100644
index 0000000000..76dfac58d9
--- /dev/null
+++ b/binaries/data/mods/public/gui/gamesetup/sprites.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/binaries/data/mods/public/gui/gamesetup/styles.xml b/binaries/data/mods/public/gui/gamesetup/styles.xml
new file mode 100644
index 0000000000..ce93f29ff3
--- /dev/null
+++ b/binaries/data/mods/public/gui/gamesetup/styles.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/gui/gui.dtd b/binaries/data/mods/public/gui/gui.dtd
index 24d1527fd3..8b0799ddc3 100644
--- a/binaries/data/mods/public/gui/gui.dtd
+++ b/binaries/data/mods/public/gui/gui.dtd
@@ -1,203 +1,203 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/gui/loading/loading.js b/binaries/data/mods/public/gui/loading/loading.js
index b1aa8e93a6..1a4464acad 100644
--- a/binaries/data/mods/public/gui/loading/loading.js
+++ b/binaries/data/mods/public/gui/loading/loading.js
@@ -1,8 +1,11 @@
-function init()
+function init(data)
{
+ var mapName = "map";
+ if (data && data.attribs)
+ mapName = data.attribs.map;
+
// Set to "hourglass" cursor.
setCursor("cursor-wait");
- console.write ("Loading " + g_GameAttributes.mapFile + " (" + g_GameAttributes.numPlayers + " players) ...");
// Choose random concept art for loading screen background (should depend on the selected civ later when this is specified).
var sprite = "";
@@ -19,10 +22,10 @@ function init()
// janwas: main loop now sets progress / description, but that won't
// happen until the first timeslice completes, so set initial values.
- getGUIObjectByName ("ldTitleBar").caption = "Loading Scenario ...";
+ getGUIObjectByName ("ldTitleBar").caption = "Loading Scenario";
getGUIObjectByName ("ldProgressBarText").caption = "";
getGUIObjectByName ("ldProgressBar").caption = 0;
- getGUIObjectByName ("ldText").caption = "LOADING " + g_GameAttributes.mapFile + " ...\nPlease wait ...";
+ getGUIObjectByName ("ldText").caption = "Loading " + mapName + "\nPlease wait...";
// Pick a random tip of the day (each line is a separate tip).
var tipArray = readFileLines("gui/text/tips.txt");
@@ -39,13 +42,10 @@ function reallyStartGame()
curr_music.fade(-1, 0.0, 5.0); // fade to 0 over 5 seconds
// This is a reserved function name that is executed by the engine when it is ready
- // to start the game (ie loading progress has reached 100%).
+ // to start the game (i.e. loading progress has reached 100%).
// Switch GUI from loading screen to game session.
- if (Engine.IsNewSimulation())
- Engine.SwitchGuiPage("page_session_new.xml");
- else
- Engine.SwitchGuiPage("page_session.xml");
+ Engine.SwitchGuiPage("page_session_new.xml");
// Restore default cursor.
setCursor ("arrow-default");
diff --git a/binaries/data/mods/public/gui/page_gamesetup.xml b/binaries/data/mods/public/gui/page_gamesetup.xml
new file mode 100644
index 0000000000..b05e6466a0
--- /dev/null
+++ b/binaries/data/mods/public/gui/page_gamesetup.xml
@@ -0,0 +1,10 @@
+
+
+ common/setup.xml
+ common/styles.xml
+ common/sprite1.xml
+ gamesetup/setup.xml
+ gamesetup/sprites.xml
+ gamesetup/styles.xml
+ gamesetup/gamesetup.xml
+
diff --git a/binaries/data/mods/public/gui/page_gamesetup_mp.xml b/binaries/data/mods/public/gui/page_gamesetup_mp.xml
new file mode 100644
index 0000000000..dc11542b22
--- /dev/null
+++ b/binaries/data/mods/public/gui/page_gamesetup_mp.xml
@@ -0,0 +1,10 @@
+
+
+ common/setup.xml
+ common/styles.xml
+ common/sprite1.xml
+ gamesetup/setup.xml
+ gamesetup/sprites.xml
+ gamesetup/styles.xml
+ gamesetup/gamesetup_mp.xml
+
diff --git a/binaries/data/mods/public/gui/pregame/mainmenu.xml b/binaries/data/mods/public/gui/pregame/mainmenu.xml
index c5c0eb471b..56132bb9fb 100644
--- a/binaries/data/mods/public/gui/pregame/mainmenu.xml
+++ b/binaries/data/mods/public/gui/pregame/mainmenu.xml
@@ -130,8 +130,7 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0
>
@@ -145,7 +144,7 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0
>
@@ -350,834 +349,6 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0
-
-
-
-
-
-
-
-
-
-
-
- Game Setup
-
-
-
-
-
-
-
-
-
-
-
-
- K
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Your Civilization:
-
-
-
- Hellenes (i)
-
-
-
-
-
-
-
-
-
- Map:
-
-
-
- Type:
-
-
-
-
-
-
-
- Name:
-
-
-
- lowerY) return 1;
- else return 0;
- });
-
- for (mapIndex = 0; mapIndex < mapArray.length; mapIndex++)
- {
- // Remove the path and extension from each name, since we just want the filename.
- // (Is there an equivalent "basename" function for that in JS?)
- mapArray[mapIndex] = mapArray[mapIndex].substring (mapPath.length, mapArray[mapIndex].length-4)
-
- // Add map name to the end of the object's list.
- pushItem (this.name, mapArray[mapIndex]);
- }
-
- // Set default value (pick whatever's at the top of the list).
-// getGUIObjectByName(this.name).selected = 0;
- // No, on second thought, set it to the randomly generated map until we can remember the last choice.
- setCurrItemValue (this.name, "Latium");
- ]]>
-
-
-
- Fog of War:
-
-
-
-
-
-
- LOS:
-
-
-
- - Normal
- - Explored
- - All Visible
-
-
-
-
-
-
-
- Map Size:
-
-
-
-
-
-
-
-
-
- [font="serif-bold-12"]Map Info[/font]
-Developed by, well, WFG.
-A large landmass with rivers, forests and coastal fishing grounds.
-
-
-
- Get more maps
-
-
-
-
-
-
-
-
- Other Players:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Game Mode:
-
-
-
-
-
-
-
- Starting Phase:
-
-
-
-
-
-
-
- Resources:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This is info text.
-
-
- tooltipText
-
-
-
-
-
-
- Screenshot Mode:
-
-
-
- this.checked = Engine.IsNewSimulation()
-
-
-
-
-
- Start!
-
-
-
- Cancel
-
-
-
-
-
-
- Please select whether you want to join a game or host your own game.
- Multiplayer
-
-
-
-
-
-
-
-
- Game Mode
-
-
- Join Game
-
-
-
-
-
- Host Game
-
-
-
-
-
-
-
-
- Host a game
-
-
-
-
-
-
-
-
- Setting up your server.
-
-
- Game (Server) Name:
-
-
- My Game
-
-
-
-
- Welcome Message:
-
-
- You can enter some message which is displayed to new players upon joining here.
-
-
- Uhm, welcome to my game. Have fun!
-
-
-
-
- Continue
-
-
-
- Back
-
-
-
-
-
-
-
- Join a game
-
-
-
-
-
-
-
-
- Joining an existing game.
-
-
- Server Hostname or IP:
-
-
- 127.0.0.1
-
-
-
-
- Continue
-
-
-
- Back
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/simulation/helpers/Commands.js b/binaries/data/mods/public/simulation/helpers/Commands.js
index cbe0ff2c79..0b20930b6c 100644
--- a/binaries/data/mods/public/simulation/helpers/Commands.js
+++ b/binaries/data/mods/public/simulation/helpers/Commands.js
@@ -7,6 +7,10 @@ function ProcessCommand(player, cmd)
switch (cmd.type)
{
+ case "debug-print":
+ print(cmd.message);
+ break;
+
case "walk":
for each (var ent in cmd.entities)
{
@@ -120,7 +124,7 @@ function ProcessCommand(player, cmd)
break;
default:
- print("Ignoring unrecognised command type '" + cmd.type + "'\n");
+ error("Ignoring unrecognised command type '" + cmd.type + "'");
}
}
diff --git a/binaries/data/mods/public/temp/players.xml b/binaries/data/mods/public/temp/players.xml
deleted file mode 100644
index 48a596b6b1..0000000000
--- a/binaries/data/mods/public/temp/players.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/binaries/data/mods/public/temp/terrain.png b/binaries/data/mods/public/temp/terrain.png
deleted file mode 100644
index 4dfa120840..0000000000
--- a/binaries/data/mods/public/temp/terrain.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:be0493a6e08619bf0d26dc3180e7a92d1f06f541aaa68ab878b701835c7220d2
-size 43135
diff --git a/build/premake/extern_libs.lua b/build/premake/extern_libs.lua
index f1a4616e6a..852c572cd2 100644
--- a/build/premake/extern_libs.lua
+++ b/build/premake/extern_libs.lua
@@ -71,8 +71,8 @@ end
-- * defines: a table of symbols to define
extern_lib_defs = {
boost = {
- unix_names = { "boost_signals-mt", "boost_filesystem-mt", "boost_system-mt" },
- osx_names = { "boost_signals-mt", "boost_filesystem-mt", "boost_system-mt" }
+ unix_names = { "boost_signals-mt", "boost_filesystem-mt", "boost_system-mt", "boost_random-mt" },
+ osx_names = { "boost_signals-mt", "boost_filesystem-mt", "boost_system-mt", "boost_random-mt" }
},
cryptopp = {
win_names = { "cryptopp" },
diff --git a/docs/doxygen/config b/docs/doxygen/config
index d514b37705..64d5bb8fbc 100644
--- a/docs/doxygen/config
+++ b/docs/doxygen/config
@@ -3,7 +3,7 @@ PROJECT_NUMBER = trunk
TAB_SIZE = 4
-INPUT = ../../source/simulation2 ../../source/scriptinterface
+INPUT = ../../source/simulation2 ../../source/scriptinterface ../../source/network
INCLUDE_PATH = ../../source
EXAMPLE_PATH = ../../source
RECURSIVE = YES
diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp
index 53ca57330d..d3515f7ddd 100644
--- a/source/graphics/GameView.cpp
+++ b/source/graphics/GameView.cpp
@@ -244,7 +244,7 @@ void CGameViewImpl::ScriptingInit()
CJSObject::ScriptingInit("GameView");
}
-int CGameView::Initialize(CGameAttributes* UNUSED(pAttribs))
+int CGameView::Initialize()
{
CFG_GET_SYS_VAL( "view.scroll.speed", Float, m->ViewScrollSpeed );
CFG_GET_SYS_VAL( "view.rotate.speed", Float, m->ViewRotateSensitivity );
@@ -267,10 +267,10 @@ int CGameView::Initialize(CGameAttributes* UNUSED(pAttribs))
-void CGameView::RegisterInit(CGameAttributes *pAttribs)
+void CGameView::RegisterInit()
{
// CGameView init
- RegMemFun1(this, &CGameView::Initialize, pAttribs, L"CGameView init", 1);
+ RegMemFun(this, &CGameView::Initialize, L"CGameView init", 1);
// previously done by CGameView::InitResources
RegMemFun(g_TexMan.GetSingletonPtr(), &CTextureManager::LoadTerrainTextures, L"LoadTerrainTextures", 60);
diff --git a/source/graphics/GameView.h b/source/graphics/GameView.h
index b96345d4cb..4d34798bc9 100644
--- a/source/graphics/GameView.h
+++ b/source/graphics/GameView.h
@@ -27,7 +27,6 @@ extern float g_YMinOffset;
#include "lib/input.h" // InReaction - can't forward-declare enum
class CGame;
-class CGameAttributes;
class CObjectManager;
class CCamera;
class CCinemaManager;
@@ -67,8 +66,8 @@ public:
void SetViewport(const SViewPort& vp);
- void RegisterInit(CGameAttributes *pAttribs);
- int Initialize(CGameAttributes *pGameAttributes);
+ void RegisterInit();
+ int Initialize();
CObjectManager& GetObjectManager() const;
diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp
index 162e7b933a..d243cffa8b 100644
--- a/source/graphics/MapReader.cpp
+++ b/source/graphics/MapReader.cpp
@@ -269,9 +269,12 @@ private:
// # entities+nonentities processed and total (for progress calc)
int completed_jobs, total_jobs;
+ // maximum used entity ID, so we can safely allocate new ones
+ entity_id_t max_uid;
void Init(const VfsPath& xml_filename);
+ void ReadPlayers();
void ReadTerrain(XMBElement parent);
void ReadEnvironment(XMBElement parent);
void ReadCamera(XMBElement parent);
@@ -325,26 +328,73 @@ void CXMLReader::Init(const VfsPath& xml_filename)
// Find the maximum entity ID, so we can safely allocate new IDs without conflicts
- int max_uid = SYSTEM_ENTITY;
+ max_uid = SYSTEM_ENTITY;
XMBElement ents = nodes.GetFirstNamedItem(xmb_file.GetElementID("Entities"));
XERO_ITER_EL(ents, ent)
{
utf16string uid = ent.GetAttributes().GetNamedItem(at_uid);
- max_uid = std::max(max_uid, CStr(uid).ToInt());
+ max_uid = std::max(max_uid, (entity_id_t)CStr(uid).ToInt());
}
// Initialise player data
+ ReadPlayers();
+}
+
+void CXMLReader::ReadPlayers()
+{
CmpPtr cmpPlayerMan(*m_MapReader.pSimulation2, SYSTEM_ENTITY);
debug_assert(!cmpPlayerMan.null());
- // TODO: this should be loaded from the XML instead
- size_t numPlayers = 4;
+ // TODO: we ought to read at least some of this data from the map file.
+ // For now, just always use the defaults.
+
+ std::map playerDefaultNames;
+ std::map playerDefaultCivs;
+ std::map playerDefaultColours;
+
+ CXeromyces playerDefaultFile;
+ if (playerDefaultFile.Load(L"simulation/data/players.xml") != PSRETURN_OK)
+ throw PSERROR_File_ReadFailed();
+
+#define AT(x) int at_##x = playerDefaultFile.GetAttributeID(#x)
+ AT(id);
+ AT(name);
+ AT(civ);
+ AT(r); AT(g); AT(b);
+#undef AT
+
+ XERO_ITER_EL(playerDefaultFile.GetRoot(), player)
+ {
+ XMBAttributeList attrs = player.GetAttributes();
+ int id = CStr(attrs.GetNamedItem(at_id)).ToInt();
+
+ playerDefaultNames[id] = attrs.GetNamedItem(at_name);
+ playerDefaultCivs[id] = attrs.GetNamedItem(at_civ);
+
+ SColor3ub colour;
+ colour.R = (u8)CStr(attrs.GetNamedItem(at_r)).ToInt();
+ colour.G = (u8)CStr(attrs.GetNamedItem(at_g)).ToInt();
+ colour.B = (u8)CStr(attrs.GetNamedItem(at_b)).ToInt();
+ playerDefaultColours[id] = colour;
+ }
+
+ size_t numPlayers = 9; // including Gaia
+
for (size_t i = 0; i < numPlayers; ++i)
{
int uid = ++max_uid;
entity_id_t ent = m_MapReader.pSimulation2->AddEntity(L"special/player", uid);
+ CmpPtr cmpPlayer(*m_MapReader.pSimulation2, ent);
+ debug_assert(!cmpPlayer.null());
+
+ cmpPlayer->SetName(playerDefaultNames[i]);
+ cmpPlayer->SetCiv(playerDefaultCivs[i]);
+
+ SColor3ub colour = playerDefaultColours[i];
+ cmpPlayer->SetColour(colour.R, colour.G, colour.B);
+
cmpPlayerMan->AddPlayer(ent);
}
}
@@ -1013,10 +1063,6 @@ int CXMLReader::ReadOldEntities(XMBElement parent, double end_time)
debug_warn(L"Invalid map XML data");
}
- CPlayer* player = NULL;
- if (g_Game)
- player = g_Game->GetPlayer(PlayerID);
-
// The old version uses a flat entity naming system, so we need
// to translate it into the hierarchical filename
if (TemplateName.Find(L"flora") == 0 || TemplateName.Find(L"fauna") == 0 || TemplateName.Find(L"geology") == 0 || TemplateName.Find(L"special") == 0)
diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp
index 23e77ce1ea..acf6aa639f 100644
--- a/source/graphics/MapWriter.cpp
+++ b/source/graphics/MapWriter.cpp
@@ -35,8 +35,8 @@
#include "maths/MathUtil.h"
#include "maths/NUSpline.h"
+#include "ps/Game.h"
#include "ps/Loader.h"
-#include "ps/Player.h"
#include "ps/Filesystem.h"
#include "ps/XML/XMLWriter.h"
#include "renderer/SkyManager.h"
diff --git a/source/graphics/Material.cpp b/source/graphics/Material.cpp
index 7bd560843d..54128f8767 100644
--- a/source/graphics/Material.cpp
+++ b/source/graphics/Material.cpp
@@ -17,9 +17,9 @@
#include "precompiled.h"
-#include "lib/ogl.h"
#include "Material.h"
-#include "ps/Player.h"
+
+#include "lib/ogl.h"
#include "ps/Game.h"
#include "ps/Overlay.h" // for CColor
@@ -106,12 +106,8 @@ SMaterialColor CMaterial::GetPlayerColor()
if (m_PlayerID <= PLAYER_ID_LAST_VALID)
{
- CPlayer* player = g_Game->GetPlayer(m_PlayerID);
- if (player)
- {
- const SPlayerColour& c (player->GetColour());
- return SMaterialColor(c.r, c.g, c.b, c.a);
- }
+ CColor c(g_Game->GetPlayerColour(m_PlayerID));
+ return SMaterialColor(c.r, c.g, c.b, c.a);
}
// Oops, something failed.
diff --git a/source/graphics/Unit.cpp b/source/graphics/Unit.cpp
index 9ddf107f64..6d09bbcf44 100644
--- a/source/graphics/Unit.cpp
+++ b/source/graphics/Unit.cpp
@@ -26,9 +26,6 @@
#include "SkeletonAnimDef.h"
#include "UnitAnimation.h"
-#include "ps/Game.h"
-#include "ps/Player.h"
-
CUnit::CUnit(CObjectEntry* object, CObjectManager& objectManager,
const std::set& actorSelections)
: m_Object(object), m_Model(object->m_Model->Clone()),
diff --git a/source/graphics/UnitManager.cpp b/source/graphics/UnitManager.cpp
index f3585b6e39..52023b4360 100644
--- a/source/graphics/UnitManager.cpp
+++ b/source/graphics/UnitManager.cpp
@@ -35,7 +35,8 @@
///////////////////////////////////////////////////////////////////////////////
// CUnitManager constructor
-CUnitManager::CUnitManager()
+CUnitManager::CUnitManager() :
+ m_ObjectManager(NULL)
{
}
diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp
index 7443d055ea..32c6c347bc 100644
--- a/source/gui/MiniMap.cpp
+++ b/source/gui/MiniMap.cpp
@@ -33,9 +33,7 @@
#include "lib/bits.h"
#include "lib/timer.h"
#include "lib/sysdep/cpu.h"
-#include "network/NetMessage.h"
#include "ps/Game.h"
-#include "ps/Player.h"
#include "ps/Profile.h"
#include "ps/World.h"
#include "renderer/Renderer.h"
diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp
index 78430892de..69d780277d 100644
--- a/source/gui/scripting/ScriptFunctions.cpp
+++ b/source/gui/scripting/ScriptFunctions.cpp
@@ -22,11 +22,14 @@
#include "graphics/Camera.h"
#include "graphics/GameView.h"
#include "gui/GUIManager.h"
+#include "lib/sysdep/sysdep.h"
#include "maths/FixedVector3D.h"
+#include "network/NetClient.h"
+#include "network/NetServer.h"
+#include "network/NetTurnManager.h"
#include "ps/CLogger.h"
#include "ps/Game.h"
#include "ps/Overlay.h"
-#include "ps/Player.h"
#include "ps/GameSetup/Config.h"
#include "simulation2/Simulation2.h"
#include "simulation2/components/ICmpCommandQueue.h"
@@ -34,6 +37,8 @@
#include "simulation2/components/ICmpTemplateManager.h"
#include "simulation2/helpers/Selection.h"
+#include "js/jsapi.h"
+
/*
* This file defines a set of functions that are available to GUI scripts, to allow
* interaction with the rest of the engine.
@@ -82,8 +87,8 @@ CScriptVal GuiInterfaceCall(void* cbdata, std::wstring name, CScriptVal data)
return JSVAL_VOID;
int player = -1;
- if (g_Game && g_Game->GetLocalPlayer())
- player = g_Game->GetLocalPlayer()->GetPlayerID();
+ if (g_Game)
+ player = g_Game->GetPlayerID();
CScriptValRooted arg (sim->GetScriptInterface().GetContext(), sim->GetScriptInterface().CloneValueFromOtherContext(guiManager->GetScriptInterface(), data.get()));
CScriptVal ret (gui->ScriptCall(player, name, arg.get()));
@@ -133,11 +138,107 @@ std::wstring SetCursor(void* UNUSED(cbdata), std::wstring name)
int GetPlayerID(void* UNUSED(cbdata))
{
- if (g_Game && g_Game->GetLocalPlayer())
- return g_Game->GetLocalPlayer()->GetPlayerID();
+ if (g_Game)
+ return g_Game->GetPlayerID();
return -1;
}
+std::wstring GetDefaultPlayerName(void* UNUSED(cbdata))
+{
+ // TODO: this should come from a config file or something
+ std::wstring name = sys_get_user_name();
+ if (name.empty())
+ name = L"anonymous";
+ return name;
+}
+
+void StartNetworkGame(void* UNUSED(cbdata))
+{
+ debug_assert(g_NetServer);
+ g_NetServer->StartGame();
+}
+
+void StartGame(void* cbdata, CScriptVal attribs, int playerID)
+{
+ CGUIManager* guiManager = static_cast (cbdata);
+
+ debug_assert(!g_NetServer);
+ debug_assert(!g_NetClient);
+
+ debug_assert(!g_Game);
+ g_Game = new CGame();
+
+ // Convert from GUI script context to sim script context
+ CSimulation2* sim = g_Game->GetSimulation2();
+ CScriptValRooted gameAttribs (sim->GetScriptInterface().GetContext(),
+ sim->GetScriptInterface().CloneValueFromOtherContext(guiManager->GetScriptInterface(), attribs.get()));
+
+ g_Game->SetPlayerID(playerID);
+ g_Game->StartGame(gameAttribs);
+}
+
+void SetNetworkGameAttributes(void* cbdata, CScriptVal attribs)
+{
+ CGUIManager* guiManager = static_cast (cbdata);
+
+ debug_assert(g_NetServer);
+
+ // Convert from GUI script context to net server script context
+ CScriptValRooted gameAttribs (g_NetServer->GetScriptInterface().GetContext(),
+ g_NetServer->GetScriptInterface().CloneValueFromOtherContext(guiManager->GetScriptInterface(), attribs.get()));
+
+ g_NetServer->UpdateGameAttributes(gameAttribs);
+}
+
+void StartNetworkHost(void* UNUSED(cbdata), std::wstring playerName)
+{
+ debug_assert(!g_NetClient);
+ debug_assert(!g_NetServer);
+ debug_assert(!g_Game);
+
+ g_NetServer = new CNetServer();
+ bool ok = g_NetServer->SetupConnection();
+ debug_assert(ok); // TODO: need better error handling
+
+ g_Game = new CGame();
+ g_NetClient = new CNetClient(g_Game);
+ g_NetClient->SetUserName(playerName);
+ g_NetClient->SetupLocalConnection(*g_NetServer);
+}
+
+void StartNetworkJoin(void* UNUSED(cbdata), std::wstring playerName, std::string serverAddress)
+{
+ debug_assert(!g_NetClient);
+ debug_assert(!g_NetServer);
+ debug_assert(!g_Game);
+
+ g_Game = new CGame();
+ g_NetClient = new CNetClient(g_Game);
+ g_NetClient->SetUserName(playerName);
+ g_NetClient->SetupConnection(serverAddress);
+}
+
+// TODO: we need some way to disconnect the server/client
+
+CScriptVal PollNetworkClient(void* cbdata)
+{
+ CGUIManager* guiManager = static_cast (cbdata);
+
+ debug_assert(g_NetClient);
+
+ CScriptValRooted poll = g_NetClient->GuiPoll();
+
+ // Convert from net client context to GUI script context
+ return guiManager->GetScriptInterface().CloneValueFromOtherContext(g_NetClient->GetScriptInterface(), poll.get());
+}
+
+void AssignNetworkPlayer(void* UNUSED(cbdata), int playerID, std::string guid)
+{
+ debug_assert(g_NetServer);
+
+ g_NetServer->AssignPlayer(playerID, guid);
+}
+
} // namespace
void GuiScriptingInit(ScriptInterface& scriptInterface)
@@ -158,7 +259,17 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
scriptInterface.RegisterFunction, int, int, int, int, int, &PickFriendlyEntitiesInRect>("PickFriendlyEntitiesInRect");
scriptInterface.RegisterFunction("GetTerrainAtPoint");
+ // Network / game setup functions
+ scriptInterface.RegisterFunction("StartNetworkGame");
+ scriptInterface.RegisterFunction("StartGame");
+ scriptInterface.RegisterFunction("StartNetworkHost");
+ scriptInterface.RegisterFunction("StartNetworkJoin");
+ scriptInterface.RegisterFunction("PollNetworkClient");
+ scriptInterface.RegisterFunction("SetNetworkGameAttributes");
+ scriptInterface.RegisterFunction("AssignNetworkPlayer");
+
// Misc functions
scriptInterface.RegisterFunction("SetCursor");
scriptInterface.RegisterFunction("GetPlayerID");
+ scriptInterface.RegisterFunction("GetDefaultPlayerName");
}
diff --git a/source/main.cpp b/source/main.cpp
index 4c99c8639d..f2b8c2691b 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -41,25 +41,27 @@ that of Atlas depending on commandline parameters.
#include "lib/external_libraries/sdl.h"
#include "lib/res/sound/snd_mgr.h"
+#include "ps/CConsole.h"
+#include "ps/Filesystem.h"
+#include "ps/Game.h"
+#include "ps/Globals.h"
+#include "ps/Hotkey.h"
+#include "ps/Loader.h"
+#include "ps/Profile.h"
+#include "ps/Pyrogenesis.h"
+#include "ps/Util.h"
+#include "ps/VideoMode.h"
#include "ps/GameSetup/GameSetup.h"
#include "ps/GameSetup/Atlas.h"
#include "ps/GameSetup/Config.h"
#include "ps/GameSetup/CmdLineArgs.h"
-#include "ps/Loader.h"
-#include "ps/Filesystem.h"
-#include "ps/CConsole.h"
-#include "ps/Profile.h"
-#include "ps/Util.h"
-#include "ps/Game.h"
-#include "ps/Hotkey.h"
-#include "ps/Globals.h"
-#include "ps/VideoMode.h"
#include "ps/XML/Xeromyces.h"
#include "network/NetClient.h"
#include "network/NetServer.h"
#include "network/NetSession.h"
#include "graphics/Camera.h"
#include "graphics/GameView.h"
+#include "scripting/ScriptingHost.h"
#include "simulation2/Simulation2.h"
#include "sound/CMusicPlayer.h"
#include "gui/GUIManager.h"
@@ -228,7 +230,7 @@ static void Frame()
// If we are not running a multiplayer game, disable updates when the game is
// minimized or out of focus and relinquish the CPU a bit, in order to make
// debugging easier.
- if( !g_NetClient && !g_NetServer && !g_app_has_focus )
+ if( !g_NetClient && !g_app_has_focus )
{
need_update = false;
// don't use SDL_WaitEvent: don't want the main loop to freeze until app focus is restored
diff --git a/source/network/JSEvents.h b/source/network/JSEvents.h
deleted file mode 100644
index 27beac899d..0000000000
--- a/source/network/JSEvents.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Copyright (C) 2009 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it 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.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D. If not, see .
- */
-
-#ifndef INCLUDED_NETWORK_JSEVENTS
-#define INCLUDED_NETWORK_JSEVENTS
-
-#include "ServerSession.h"
-#include "scripting/DOMEvent.h"
-
-enum ENetworkJSEvents
-{
- NET_JS_EVENT_START_GAME,
- NET_JS_EVENT_CHAT,
- NET_JS_EVENT_CONNECT_COMPLETE,
- NET_JS_EVENT_DISCONNECT,
- NET_JS_EVENT_CLIENT_CONNECT,
- NET_JS_EVENT_CLIENT_DISCONNECT,
- NET_JS_EVENT_LAST
-};
-
-class CStartGameEvent: public CScriptEvent
-{
-public:
- CStartGameEvent():
- CScriptEvent(L"startGame", NET_JS_EVENT_START_GAME, false)
- {}
-};
-
-class CChatEvent: public CScriptEvent
-{
- CStrW m_Sender;
- CStrW m_Message;
-
-public:
- CChatEvent(const CStrW& sender, const CStrW& message):
- CScriptEvent(L"chat", NET_JS_EVENT_CHAT, false ),
- m_Sender(sender),
- m_Message(message)
- {
- AddLocalProperty(L"sender", &m_Sender, true);
- AddLocalProperty(L"message", &m_Message, true);
- }
-};
-
-class CConnectCompleteEvent: public CScriptEvent
-{
- CStrW m_Message;
- bool m_Success;
-
-public:
- CConnectCompleteEvent(const CStrW& message, bool success):
- CScriptEvent(L"connectComplete", NET_JS_EVENT_CONNECT_COMPLETE, false),
- m_Message(message),
- m_Success(success)
- {
- AddLocalProperty(L"message", &m_Message, true);
- AddLocalProperty(L"success", &m_Success, true);
- }
-};
-
-class CDisconnectEvent: public CScriptEvent
-{
- CStrW m_Message;
-
-public:
- CDisconnectEvent(const CStrW& message):
- CScriptEvent(L"disconnect", NET_JS_EVENT_DISCONNECT, false),
- m_Message(message)
- {
- AddLocalProperty(L"message", &m_Message, true);
- }
-};
-
-class CClientConnectDisconnectCommon: public CScriptEvent
-{
- int m_SessionID;
- CStrW m_Name;
- CNetServerSession *m_pSession;
-
-public:
- CClientConnectDisconnectCommon(const wchar_t* UNUSED(eventName), int UNUSED(eventType),
- int sessionID, const CStrW& name, CNetServerSession* pSession)
- : CScriptEvent(L"clientConnect", NET_JS_EVENT_CLIENT_CONNECT, false),
- m_SessionID(sessionID),
- m_Name(name),
- m_pSession(pSession)
- {
- AddLocalProperty(L"id", &m_SessionID, true);
- AddLocalProperty(L"name", &m_Name, true);
- if (m_pSession)
- AddLocalProperty(L"session", &m_pSession, true);
- }
-};
-
-struct CClientConnectEvent: public CClientConnectDisconnectCommon
-{
- CClientConnectEvent(int sessionID, const CStrW& name):
- CClientConnectDisconnectCommon(
- L"clientConnect",
- NET_JS_EVENT_CLIENT_CONNECT,
- sessionID,
- name,
- NULL)
- {}
-
- CClientConnectEvent(CNetServerSession *pSession):
- CClientConnectDisconnectCommon(
- L"clientConnect",
- NET_JS_EVENT_CLIENT_CONNECT,
- pSession->GetID(),
- pSession->GetName(),
- pSession)
- {}
-};
-
-struct CClientDisconnectEvent: public CClientConnectDisconnectCommon
-{
- CClientDisconnectEvent(int sessionID, const CStrW& name):
- CClientConnectDisconnectCommon(
- L"clientDisconnect",
- NET_JS_EVENT_CLIENT_DISCONNECT,
- sessionID,
- name,
- NULL)
- {}
-
- CClientDisconnectEvent(CNetServerSession *pSession):
- CClientConnectDisconnectCommon(
- L"clientDisconnect",
- NET_JS_EVENT_CLIENT_DISCONNECT,
- pSession->GetID(),
- pSession->GetName(),
- pSession)
- {}
-};
-
-#endif
diff --git a/source/network/NetClient.cpp b/source/network/NetClient.cpp
index cbdd197727..27c8bad5a2 100644
--- a/source/network/NetClient.cpp
+++ b/source/network/NetClient.cpp
@@ -15,623 +15,380 @@
* along with 0 A.D. If not, see .
*/
-/**
- *-----------------------------------------------------------------------------
- * FILE : NetClient.cpp
- * PROJECT : 0 A.D.
- * DESCRIPTION : Network client class implementation file
- *-----------------------------------------------------------------------------
- */
-
-// INCLUDES
#include "precompiled.h"
#include "NetClient.h"
-#include "NetJsEvents.h"
-#include "Network.h"
-#include "NetServer.h"
+#include "NetMessage.h"
+#include "NetSession.h"
+#include "NetTurnManager.h"
-#include "scripting/DOMEvent.h"
-#include "scripting/JSConversions.h"
-#include "scripting/ScriptableObject.h"
#include "ps/CConsole.h"
#include "ps/CLogger.h"
#include "ps/CStr.h"
#include "ps/Game.h"
-#include "ps/Globals.h"
-#include "ps/GameAttributes.h"
+#include "scriptinterface/ScriptInterface.h"
#include "simulation2/Simulation2.h"
-// DECLARATIONS
-
-#define LOG_CATEGORY L"net"
+#include
+#include
CNetClient *g_NetClient = NULL;
-//-----------------------------------------------------------------------------
-// Name: CServerPlayer()
-// Desc: Constructor
-//-----------------------------------------------------------------------------
-CServerPlayer::CServerPlayer( uint sessionID, const CStr& nickname )
+CNetClient::CNetClient(CGame* game) :
+ m_Session(NULL),
+ m_UserName(L"anonymous"),
+ m_GUID(GenerateGUID()), m_HostID((u32)-1), m_ClientTurnManager(NULL), m_Game(game)
{
- m_SessionID = sessionID;
- m_Nickname = nickname;
-}
+ m_Game->SetTurnManager(NULL); // delete the old local turn manager so we don't accidentally use it
-//-----------------------------------------------------------------------------
-// Name: ~CServerPlayer()
-// Desc: Destructor
-//-----------------------------------------------------------------------------
-CServerPlayer::~CServerPlayer( void )
-{
-}
+ void* context = this;
-//-----------------------------------------------------------------------------
-// Name: ScriptingInit()
-// Desc:
-//-----------------------------------------------------------------------------
-void CServerPlayer::ScriptingInit( void )
-{
- AddProperty(L"id", &CServerPlayer::m_SessionID, true);
- AddProperty(L"name", &CServerPlayer::m_Nickname, true);
+ // Set up transitions for session
+ AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, (void*)&OnConnect, context);
- CJSObject::ScriptingInit( "NetClient_ServerSession" );
-}
+ AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, (void*)&OnHandshake, context);
-//-----------------------------------------------------------------------------
-// Name: CNetClient()
-// Desc: Constructor
-//-----------------------------------------------------------------------------
-CNetClient::CNetClient( ScriptInterface& scriptInterface, CGame* pGame, CGameAttributes* pGameAttribs )
-: CNetHost( scriptInterface ), m_JsPlayers( &m_Players )
-{
- m_ClientTurnManager = NULL;
+ AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, (void*)&OnHandshakeResponse, context);
- m_pLocalPlayerSlot = NULL;
- m_pGame = pGame;
- m_pGameAttributes = pGameAttribs;
+ AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_INITIAL_GAMESETUP, (void*)&OnAuthenticate, context);
- g_ScriptingHost.SetGlobal("g_NetClient", OBJECT_TO_JSVAL(GetScript()));
-}
+ AddTransition(NCS_INITIAL_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context);
-//-----------------------------------------------------------------------------
-// Name: ~CNetClient()
-// Desc: Destructor
-//-----------------------------------------------------------------------------
-CNetClient::~CNetClient()
-{
- // Release resources
- PlayerMap::iterator it = m_Players.begin();
- for ( ; it != m_Players.end(); it++ )
- {
- CServerPlayer *pCurrPlayer = it->second;
- if ( pCurrPlayer ) delete pCurrPlayer;
- }
+ AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context);
+ AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context);
+ AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context);
- m_Players.clear();
+ AddTransition(NCS_LOADING, (uint)NMT_GAME_SETUP, NCS_LOADING, (void*)&OnGameSetup, context);
+ AddTransition(NCS_LOADING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_LOADING, (void*)&OnPlayerAssignment, context);
+ AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context);
- g_ScriptingHost.SetGlobal("g_NetClient", JSVAL_NULL);
-}
+ AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, (void*)&OnGameSetup, context);
+ AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, (void*)&OnPlayerAssignment, context);
+ AddTransition(NCS_INGAME, (uint)NMT_SIMULATION_COMMAND, NCS_INGAME, (void*)&OnInGame, context);
+ AddTransition(NCS_INGAME, (uint)NMT_SYNC_ERROR, NCS_INGAME, (void*)&OnInGame, context);
+ AddTransition(NCS_INGAME, (uint)NMT_END_COMMAND_BATCH, NCS_INGAME, (void*)&OnInGame, context);
-//-----------------------------------------------------------------------------
-// Name: ScriptingInit()
-// Desc:
-//-----------------------------------------------------------------------------
-void CNetClient::ScriptingInit()
-{
- AddMethod("beginConnect", 1);
-
- AddProperty(L"onStartGame", &CNetClient::m_OnStartGame);
- AddProperty(L"onChat", &CNetClient::m_OnChat);
- AddProperty(L"onConnectComplete", &CNetClient::m_OnConnectComplete);
- AddProperty(L"onDisconnect", &CNetClient::m_OnDisconnect);
- AddProperty(L"onClientConnect", &CNetClient::m_OnPlayerJoin);
- AddProperty(L"onClientDisconnect", &CNetClient::m_OnPlayerLeave);
-
- AddProperty(L"password", &CNetClient::m_Password);
- AddProperty(L"playerName", &CNetClient::m_Nickname);
-
- AddProperty(L"sessions", &CNetClient::m_JsPlayers);
-
- CJSMap< PlayerMap >::ScriptingInit("NetClient_SessionMap");
- CJSObject::ScriptingInit("NetClient");
-}
-
-//-----------------------------------------------------------------------------
-// Name: Run()
-// Desc: Connect to server and start main loop
-//-----------------------------------------------------------------------------
-bool CNetClient::SetupConnection( JSContext* UNUSED(pContext), uintN argc, jsval* argv )
-{
- uint port = DEFAULT_HOST_PORT;
-
- // Validate parameters
- if ( argc == 0 ) return false;
-
- // Build host information
- CStr host = g_ScriptingHost.ValueToString( argv[0] );
- if ( argc == 2 ) port = ToPrimitive< uint >( argv[ 1 ] );
-
- // Create client host
- if ( !Create() ) return false;
-
- // Connect to server
- return Connect( host, port );
-}
-
-//-----------------------------------------------------------------------------
-// Name: SetupSession()
-// Desc: Setup client session upon creation
-//-----------------------------------------------------------------------------
-bool CNetClient::SetupSession( CNetSession* pSession )
-{
- // Validate parameters
- if ( !pSession ) return false;
-
- FsmActionCtx* pContext = pSession->GetFsmActionCtx();
-
- pContext->pHost = this;
- pContext->pSession = pSession;
-
- // Setup transitions for session
- pSession->AddTransition( NCS_CONNECT, ( uint )NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, (void*)&OnHandshake, pContext );
-
- pSession->AddTransition( NCS_HANDSHAKE, ( uint )NMT_ERROR, NCS_CONNECT, (void*)&OnError, pContext );
- pSession->AddTransition( NCS_HANDSHAKE, ( uint )NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, (void*)&OnHandshake, pContext );
-
- pSession->AddTransition( NCS_AUTHENTICATE, ( uint )NMT_ERROR, NCS_CONNECT, (void*)&OnError, pContext );
- pSession->AddTransition( NCS_AUTHENTICATE, ( uint )NMT_AUTHENTICATE_RESULT, NCS_PREGAME, (void*)&OnAuthenticate, pContext );
-
- pSession->AddTransition( NCS_PREGAME, ( uint )NMT_ERROR, NCS_CONNECT, (void*)&OnError, pContext );
- pSession->AddTransition( NCS_PREGAME, ( uint )NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnPreGame, pContext );
- pSession->AddTransition( NCS_PREGAME, ( uint )NMT_ASSIGN_PLAYER_SLOT, NCS_PREGAME, (void*)&OnPreGame, pContext );
- pSession->AddTransition( NCS_PREGAME, ( uint )NMT_PLAYER_CONFIG, NCS_PREGAME, (void*)&OnPreGame, pContext );
- pSession->AddTransition( NCS_PREGAME, ( uint )NMT_PLAYER_JOIN, NCS_PREGAME, (void*)&OnPlayerJoin, pContext );
- pSession->AddTransition( NCS_PREGAME, ( uint )NMT_GAME_START, NCS_INGAME, (void*)&OnStartGame_, pContext );
-
- pSession->AddTransition( NCS_INGAME, ( uint )NMT_CHAT, NCS_INGAME, (void*)&OnChat, pContext );
- pSession->AddTransition( NCS_INGAME, ( uint )NMT_SIMULATION_COMMAND, NCS_INGAME, (void*)&OnInGame, pContext );
- pSession->AddTransition( NCS_INGAME, ( uint )NMT_SYNC_ERROR, NCS_INGAME, (void*)&OnInGame, pContext );
- pSession->AddTransition( NCS_INGAME, ( uint )NMT_END_COMMAND_BATCH, NCS_INGAME, (void*)&OnInGame, pContext );
+ // TODO: add chat
// Set first state
- pSession->SetFirstState( NCS_CONNECT );
-
- return true;
+ SetFirstState(NCS_UNCONNECTED);
}
-//-----------------------------------------------------------------------------
-// Name: HandleConnect()
-// Desc: Called when the client successfully connected to server
-//-----------------------------------------------------------------------------
-bool CNetClient::HandleConnect( CNetSession* pSession )
+CNetClient::~CNetClient()
{
- // Validate parameters
- if ( !pSession ) return false;
-
- return true;
+ delete m_Session;
}
-//-----------------------------------------------------------------------------
-// Name: HandleDisconnect()
-// Desc: Called when the client disconnected from the server
-//-----------------------------------------------------------------------------
-bool CNetClient::HandleDisconnect( CNetSession *pSession )
+void CNetClient::SetUserName(const CStrW& username)
{
- // Validate parameters
- if ( !pSession ) return false;
+ debug_assert(!m_Session); // must be called before we start the connection
- return true;
+ m_UserName = username;
}
-//-----------------------------------------------------------------------------
-// Name: OnError()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnError( void* pContext, CFsmEvent* pEvent )
+bool CNetClient::SetupConnection(const CStr& server)
{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
+ CNetClientSessionRemote* session = new CNetClientSessionRemote(*this);
+ bool ok = session->Connect(PS_DEFAULT_PORT, server);
+ SetAndOwnSession(session);
+ return ok;
+}
- // Error event?
- if ( pEvent->GetType() != (uint)NMT_ERROR ) return true;
+void CNetClient::SetupLocalConnection(CNetServer& server)
+{
+ CNetClientSessionLocal* session = new CNetClientSessionLocal(*this, server);
+ SetAndOwnSession(session);
+}
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
- debug_assert( pClient );
+void CNetClient::SetAndOwnSession(CNetClientSession* session)
+{
+ delete m_Session;
+ m_Session = session;
+}
- CErrorMessage* pMessage = ( CErrorMessage* )pEvent->GetParamRef();
- if ( pMessage )
+void CNetClient::Poll()
+{
+ if (m_Session)
+ m_Session->Poll();
+}
+
+CScriptValRooted CNetClient::GuiPoll()
+{
+ if (m_GuiMessageQueue.empty())
+ return CScriptValRooted();
+
+ CScriptValRooted r = m_GuiMessageQueue.front();
+ m_GuiMessageQueue.pop_front();
+ return r;
+}
+
+void CNetClient::PushGuiMessage(const CScriptValRooted& message)
+{
+ debug_assert(!message.undefined());
+
+ m_GuiMessageQueue.push_back(message);
+}
+
+std::wstring CNetClient::TestReadGuiMessages()
+{
+ std::wstring r;
+ while (true)
{
- LOG( CLogger::Error, LOG_CATEGORY, L"CNetClient::OnError(): Error description %hs", pMessage->m_Error );
+ CScriptValRooted msg = GuiPoll();
+ if (msg.undefined())
+ break;
+ r += GetScriptInterface().ToString(msg.get()) + L"\n";
+ }
+ return r;
+}
- if ( pClient->m_OnConnectComplete.Defined() )
+ScriptInterface& CNetClient::GetScriptInterface()
+{
+ return m_Game->GetSimulation2()->GetScriptInterface();
+}
+
+void CNetClient::PostPlayerAssignmentsToScript()
+{
+ CScriptValRooted msg;
+ GetScriptInterface().Eval("({'type':'players', 'hosts':{}})", msg);
+
+ CScriptValRooted hosts;
+ GetScriptInterface().GetProperty(msg.get(), "hosts", hosts);
+
+ for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it)
+ {
+ CScriptValRooted host;
+ GetScriptInterface().Eval("({})", host);
+ GetScriptInterface().SetProperty(host.get(), "name", std::wstring(it->second.m_Name), false);
+ GetScriptInterface().SetProperty(host.get(), "player", it->second.m_PlayerID, false);
+ GetScriptInterface().SetProperty(hosts.get(), it->first, host, false);
+ }
+
+ PushGuiMessage(msg);
+}
+
+bool CNetClient::SendMessage(const CNetMessage* message)
+{
+ return m_Session->SendMessage(message);
+}
+
+void CNetClient::HandleConnect()
+{
+ Update((uint)NMT_CONNECT_COMPLETE, NULL);
+}
+
+void CNetClient::HandleDisconnect()
+{
+ // TODO: should do something
+}
+
+bool CNetClient::HandleMessage(CNetMessage* message)
+{
+ // Update FSM
+ bool ok = Update(message->GetType(), message);
+ if (!ok)
+ LOGERROR(L"Net client: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)GetCurrState());
+ return ok;
+}
+
+void CNetClient::LoadFinished()
+{
+ m_Game->ChangeNetStatus(CGame::NET_WAITING_FOR_CONNECT);
+
+ CLoadedGameMessage loaded;
+ SendMessage(&loaded);
+}
+
+bool CNetClient::OnConnect(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_CONNECT_COMPLETE);
+
+ CNetClient* client = (CNetClient*)context;
+
+ CScriptValRooted msg;
+ client->GetScriptInterface().Eval("({'type':'netstatus','status':'connected'})", msg);
+ client->PushGuiMessage(msg);
+
+ return true;
+}
+
+bool CNetClient::OnHandshake(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_SERVER_HANDSHAKE);
+
+ CNetClient* client = (CNetClient*)context;
+
+ CCliHandshakeMessage handshake;
+ handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE;
+ handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
+ handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION;
+ client->SendMessage(&handshake);
+
+ return true;
+}
+
+bool CNetClient::OnHandshakeResponse(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE);
+
+ CNetClient* client = (CNetClient*)context;
+
+ CAuthenticateMessage authenticate;
+ authenticate.m_GUID = client->m_GUID;
+ authenticate.m_Name = client->m_UserName;
+ authenticate.m_Password = L""; // TODO
+ client->SendMessage(&authenticate);
+
+ return true;
+}
+
+bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT);
+
+ CNetClient* client = (CNetClient*)context;
+
+ CAuthenticateResultMessage* message = (CAuthenticateResultMessage*)event->GetParamRef();
+
+ LOGMESSAGE(L"Net: Authentication result: host=%d, %ls", message->m_HostID, message->m_Message.c_str() );
+
+ client->m_HostID = message->m_HostID;
+
+ CScriptValRooted msg;
+ client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", msg);
+ client->PushGuiMessage(msg);
+
+ return true;
+}
+
+bool CNetClient::OnGameSetup(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_GAME_SETUP);
+
+ CNetClient* client = (CNetClient*)context;
+
+ CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef();
+
+ client->m_GameAttributes = message->m_Data;
+
+ CScriptValRooted msg;
+ client->GetScriptInterface().Eval("({'type':'gamesetup'})", msg);
+ client->GetScriptInterface().SetProperty(msg.get(), "data", message->m_Data, false);
+ client->PushGuiMessage(msg);
+
+ return true;
+}
+
+bool CNetClient::OnPlayerAssignment(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_PLAYER_ASSIGNMENT);
+
+ CNetClient* client = (CNetClient*)context;
+
+ CPlayerAssignmentMessage* message = (CPlayerAssignmentMessage*)event->GetParamRef();
+
+ // Unpack the message
+ client->m_PlayerAssignments.clear();
+ for (size_t i = 0; i < message->m_Hosts.size(); ++i)
+ {
+ PlayerAssignment assignment;
+ assignment.m_Name = message->m_Hosts[i].m_Name;
+ assignment.m_PlayerID = message->m_Hosts[i].m_PlayerID;
+ client->m_PlayerAssignments[message->m_Hosts[i].m_GUID] = assignment;
+ }
+
+ client->PostPlayerAssignmentsToScript();
+
+ return true;
+}
+
+bool CNetClient::OnGameStart(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_GAME_START);
+
+ CNetClient* client = (CNetClient*)context;
+
+ // Find the player assigned to our GUID
+ int player = -1;
+ if (client->m_PlayerAssignments.find(client->m_GUID) != client->m_PlayerAssignments.end())
+ player = client->m_PlayerAssignments[client->m_GUID].m_PlayerID;
+
+ client->m_ClientTurnManager = new CNetClientTurnManager(*client->m_Game->GetSimulation2(), *client, client->m_HostID);
+
+ client->m_Game->SetPlayerID(player);
+ client->m_Game->StartGame(client->m_GameAttributes);
+
+ CScriptValRooted msg;
+ client->GetScriptInterface().Eval("({'type':'start'})", msg);
+ client->PushGuiMessage(msg);
+
+ return true;
+}
+
+bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event)
+{
+ debug_assert(event->GetType() == (uint)NMT_LOADED_GAME);
+
+ CNetClient* client = (CNetClient*)context;
+
+ // All players have loaded the game - start running the turn manager
+ // so that the game begins
+ client->m_Game->SetTurnManager(client->m_ClientTurnManager);
+ client->m_Game->ChangeNetStatus(CGame::NET_NORMAL);
+
+ return true;
+}
+
+bool CNetClient::OnInGame(void *context, CFsmEvent* event)
+{
+ // TODO: should split each of these cases into a separate method
+
+ CNetClient* client = (CNetClient*)context;
+
+ CNetMessage* message = (CNetMessage*)event->GetParamRef();
+ if (message)
+ {
+ if (message->GetType() == NMT_SIMULATION_COMMAND)
{
- CConnectCompleteEvent connectComplete( ( CStrW )pMessage->m_Error, false );
- pClient->m_OnConnectComplete.DispatchEvent( pClient->GetScript(), &connectComplete );
+ CSimulationMessage* simMessage = static_cast (message);
+ client->m_ClientTurnManager->OnSimulationMessage(simMessage);
+ }
+ else if (message->GetType() == NMT_SYNC_ERROR)
+ {
+ CSyncErrorMessage* syncMessage = static_cast (message);
+ client->m_ClientTurnManager->OnSyncError(syncMessage->m_Turn, syncMessage->m_HashExpected);
+ }
+ else if (message->GetType() == NMT_END_COMMAND_BATCH)
+ {
+ CEndCommandBatchMessage* endMessage = static_cast (message);
+ client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn);
}
}
return true;
}
-//-----------------------------------------------------------------------------
-// Name: OnPlayer()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnPlayerJoin( void* pContext, CFsmEvent* pEvent )
+CStr CNetClient::GenerateGUID()
{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
+ // TODO: Ideally this will be guaranteed unique (and verified
+ // cryptographically) since we'll rely on it to identify hosts
+ // and associate them with player controls (e.g. to support
+ // leaving/rejoining in-progress games), and we don't want
+ // a host to masquerade as someone else.
+ // For now, just try to pick a very random number.
- // Connect event?
- if ( pEvent->GetType() != NMT_PLAYER_JOIN ) return true;
+ boost::random_device rng;
+ boost::uniform_int dist(0, std::numeric_limits::max());
+ boost::variate_generator > gen(rng, dist);
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
- debug_assert( pClient );
-
- CPlayerJoinMessage* pMessage = ( CPlayerJoinMessage* )pEvent->GetParamRef();
- if ( pMessage )
+ CStr guid;
+ for (size_t i = 0; i < 2; ++i)
{
- for ( uint i = 0; i < pMessage->m_Clients.size(); i++ )
- {
- pClient->OnPlayer( pMessage->m_Clients[ i ].m_SessionID, pMessage->m_Clients[ i ].m_Name );
- }
-
- pClient->OnConnectComplete();
+ char buf[32];
+ sprintf_s(buf, ARRAY_SIZE(buf), "%08X", gen());
+ guid += buf;
}
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnConnectComplete()
-// Desc:
-//-----------------------------------------------------------------------------
-void CNetClient::OnConnectComplete( )
-{
- if ( m_OnConnectComplete.Defined() )
- {
- CConnectCompleteEvent connectComplete( "OK", true );
- m_OnConnectComplete.DispatchEvent( GetScript(), &connectComplete );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnHandshake()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnHandshake( void* pContext, CFsmEvent* pEvent )
-{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
-
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
- CNetSession* pSession = ( ( FsmActionCtx* )pContext )->pSession;
-
- debug_assert( pClient );
- debug_assert( pSession );
-
- switch ( pEvent->GetType() )
- {
- //case NMT_ERROR:
-
- // CNetClient::OnError( pContext, pEvent );
- // break;
-
- case NMT_SERVER_HANDSHAKE:
- {
- CCliHandshakeMessage handshake;
- handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE;
- handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
- handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION;
- pClient->SendMessage( pSession, &handshake );
- }
- break;
-
- case NMT_SERVER_HANDSHAKE_RESPONSE:
- {
- CAuthenticateMessage authenticate;
- authenticate.m_Name = pClient->m_Nickname;
- authenticate.m_Password = pClient->m_Password;
- pClient->SendMessage( pSession, &authenticate );
- }
- break;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnAuthenticate()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnAuthenticate( void* pContext, CFsmEvent* pEvent )
-{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
-
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
- UNUSED2(pClient);
- CNetSession* pSession = ( ( FsmActionCtx* )pContext )->pSession;
-
- debug_assert( pClient );
- debug_assert( pSession );
-
- if ( pEvent->GetType() == (uint)NMT_ERROR )
- {
- // return CNetClient::OnError( pContext, pEvent );
- }
- else if ( pEvent->GetType() == NMT_AUTHENTICATE_RESULT )
- {
- CAuthenticateResultMessage* pMessage =( CAuthenticateResultMessage* )pEvent->GetParamRef();
- if ( !pMessage ) return true;
-
- LOG(CLogger::Error, LOG_CATEGORY, L"CNetClient::OnAuthenticate(): Authentication result: %ls", pMessage->m_Message.c_str() );
-
- pSession->SetID( pMessage->m_SessionID );
-
- LOG(CLogger::Error, LOG_CATEGORY, L"CNetClient::OnAuthenticate(): My session ID is %d", pMessage->m_SessionID);
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnPreGame()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnPreGame( void* pContext, CFsmEvent* pEvent )
-{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
-
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
- CNetSession* pSession = ( CNetSession* )( ( FsmActionCtx* )pContext )->pSession;
-
- debug_assert( pClient );
- debug_assert( pSession );
-
- switch ( pEvent->GetType() )
- {
- case NMT_PLAYER_LEAVE:
- {
- CPlayerLeaveMessage* pMessage = ( CPlayerLeaveMessage* )pEvent->GetParamRef();
- if ( !pMessage ) return false;
-
- pClient->OnPlayerLeave( pMessage->m_SessionID );
- }
- break;
-
- case NMT_GAME_SETUP:
- {
- CGameSetupMessage* pMessage = ( CGameSetupMessage* )pEvent->GetParamRef();
-
- for ( uint i = 0; i < pMessage->m_Values.size(); i++ )
- {
- pClient->m_pGameAttributes->SetValue( pMessage->m_Values[ i ].m_Name, pMessage->m_Values[ i ].m_Value );
- }
- }
- break;
-
- case NMT_ASSIGN_PLAYER_SLOT:
- {
- CAssignPlayerSlotMessage* pMessage = ( CAssignPlayerSlotMessage* )pEvent->GetParamRef();
-
- // FIXME Validate slot id to prevent us from going boom
- CPlayerSlot* pSlot = pClient->m_pGameAttributes->GetSlot( pMessage->m_SlotID );
- if ( pSlot == pClient->m_pLocalPlayerSlot ) {
- pClient->m_pLocalPlayerSlot = NULL;
- }
-
- switch ( pMessage->m_Assignment )
- {
- case ASSIGN_SESSION:
- {
- // TODO: Check where is the best place to assign client's session ID
- if ( pSession->GetID() == pMessage->m_SessionID )
- {
- pClient->m_pLocalPlayerSlot = pSlot;
- }
- pSlot->AssignToSessionID( pMessage->m_SessionID );
- }
- break;
-
- case ASSIGN_CLOSED:
- pSlot->AssignClosed();
- break;
-
- case ASSIGN_OPEN:
- pSlot->AssignOpen();
- break;
-
- default:
- LOG( CLogger::Warning, LOG_CATEGORY, L"Invalid slot assignment %hs", pMessage->ToString().c_str() );
- break;
- }
- }
- break;
-
- case NMT_PLAYER_CONFIG:
- {
- CPlayerConfigMessage* pMessage = ( CPlayerConfigMessage* )pEvent->GetParamRef();
-
- // FIXME Check player ID
- CPlayer* pPlayer = pClient->m_pGameAttributes->GetPlayer( pMessage->m_PlayerID );
-
- for ( uint i = 0; i < pMessage->m_Values.size(); i++ )
- {
- pPlayer->SetValue( pMessage->m_Values[i].m_Name, pMessage->m_Values[i].m_Value );
- }
- }
- break;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnInGame()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnInGame( void *pContext, CFsmEvent* pEvent )
-{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
-
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
-
- CNetMessage* pMessage = ( CNetMessage* )pEvent->GetParamRef();
- if ( pMessage )
- {
- if (pMessage->GetType() == NMT_SIMULATION_COMMAND)
- {
- CSimulationMessage* simMessage = static_cast (pMessage);
- pClient->m_ClientTurnManager->OnSimulationMessage(simMessage);
- }
- else if (pMessage->GetType() == NMT_SYNC_ERROR)
- {
- CSyncErrorMessage* syncMessage = static_cast (pMessage);
- pClient->m_ClientTurnManager->OnSyncError(syncMessage->m_Turn, syncMessage->m_HashExpected);
- }
- else if ( pMessage->GetType() == NMT_END_COMMAND_BATCH )
- {
- CEndCommandBatchMessage* pMessage = ( CEndCommandBatchMessage* )pEvent->GetParamRef();
- if ( !pMessage ) return false;
-
- CEndCommandBatchMessage* endMessage = static_cast (pMessage);
- pClient->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn);
- }
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnChat()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnChat( void* pContext, CFsmEvent* pEvent )
-{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
-
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
-
- if ( pEvent->GetType() == NMT_CHAT )
- {
- CChatMessage* pMessage = ( CChatMessage* )pEvent->GetParamRef();
- if ( !pMessage ) return false;
-
- g_Console->ReceivedChatMessage( pMessage->m_Sender, pMessage->m_Message );
-
- if ( pClient->m_OnChat.Defined() )
- {
- CChatEvent evt( pMessage->m_Sender, pMessage->m_Message );
- pClient->m_OnChat.DispatchEvent( pClient->GetScript(), &evt );
- }
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnStartGame()
-// Desc:
-//-----------------------------------------------------------------------------
-void CNetClient::OnStartGame( void )
-{
- if ( m_OnStartGame.Defined() )
- {
- CStartGameEvent event;
- m_OnStartGame.DispatchEvent( GetScript(), &event );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnStartGame_()
-// Desc:
-//-----------------------------------------------------------------------------
-bool CNetClient::OnStartGame_( void* pContext, CFsmEvent* pEvent )
-{
- // Validate parameters
- if ( !pEvent || !pContext ) return false;
-
- CNetClient* pClient = ( CNetClient* )( ( FsmActionCtx* )pContext )->pHost;
- CNetSession* pSession = ( ( FsmActionCtx* )pContext )->pSession;
-
- pClient->m_ClientTurnManager = new CNetClientTurnManager(*pClient->m_pGame->GetSimulation2(), *pClient, pClient->GetLocalPlayer()->GetPlayerID(), pSession->GetID());
- pClient->m_pGame->SetTurnManager(pClient->m_ClientTurnManager);
-
- pClient->OnStartGame();
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnPlayerJoin()
-// Desc:
-//-----------------------------------------------------------------------------
-void CNetClient::OnPlayer( uint ID, const CStr& name )
-{
- CServerPlayer* pNewPlayer = new CServerPlayer( ID, name );
- if ( !pNewPlayer ) return;
-
- // Store new player
- m_Players[ ID ] = pNewPlayer;
-
- // Call JS Callback
- if ( m_OnPlayerJoin.Defined() )
- {
- CClientConnectEvent event( ID, name );
- m_OnPlayerJoin.DispatchEvent( GetScript(), &event );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Name: OnPlayerLeave()
-// Desc:
-//-----------------------------------------------------------------------------
-void CNetClient::OnPlayerLeave( uint ID )
-{
- // Lookup player
- PlayerMap::iterator it = m_Players.find( ID );
- if ( it == m_Players.end() )
- {
- LOG( CLogger::Warning, LOG_CATEGORY, L"CNetClient::OnPlayerLeav(): No such player %d.", ID );
- return;
- }
-
- // Call JS Callback
- if ( m_OnPlayerLeave.Defined() && it->second )
- {
- CClientDisconnectEvent event( it->second->GetSessionID(), it->second->GetNickname() );
- m_OnPlayerLeave.DispatchEvent( GetScript(), &event );
- }
-
- // Remove player from internal map
- m_Players.erase( it );
-}
-
-//-----------------------------------------------------------------------------
-// Name: StartGame()
-// Desc:
-//-----------------------------------------------------------------------------
-int CNetClient::StartGame( void )
-{
- assert ( m_pGame );
- assert ( m_pGameAttributes );
-
- if ( m_pGame->StartGame( m_pGameAttributes ) != PSRETURN_OK ) return -1;
-
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Name: GetLocalPlayer()
-// Desc:
-//-----------------------------------------------------------------------------
-CPlayer* CNetClient::GetLocalPlayer()
-{
- return m_pLocalPlayerSlot->GetPlayer();
+ return guid;
}
diff --git a/source/network/NetClient.h b/source/network/NetClient.h
index 2b9005a037..e34cde2420 100644
--- a/source/network/NetClient.h
+++ b/source/network/NetClient.h
@@ -15,131 +15,195 @@
* along with 0 A.D. If not, see .
*/
-/**
- *-----------------------------------------------------------------------------
- * FILE : NetClient.h
- * PROJECT : 0 A.D.
- * DESCRIPTION : Network client class interface file
- *-----------------------------------------------------------------------------
- */
-
#ifndef NETCLIENT_H
#define NETCLIENT_H
-// INCLUDES
-#include "NetSession.h"
-#include "NetHost.h"
-#include "NetTurnManager.h"
+#include "network/fsm.h"
+#include "network/NetHost.h"
+#include "scriptinterface/ScriptVal.h"
+
#include "ps/CStr.h"
-#include "scripting/ScriptObject.h"
-#include "scripting/ScriptableObject.h"
-#include "ps/scripting/JSMap.h"
-#include