Ticket #1504: 0ad-multiplayer-lobby-v17-06-2012.diff
File 0ad-multiplayer-lobby-v17-06-2012.diff, 68.9 KB (added by , 12 years ago) |
---|
-
build/premake/extern_libs4.lua
248 248 }) 249 249 end, 250 250 }, 251 gloox = { 252 compile_settings = function() 253 add_default_include_paths("gloox") 254 end, 255 link_settings = function() 256 add_default_links({ 257 win_names = { "gloox" }, 258 unix_names = { "gloox" }, 259 }) 260 end, 261 }, 251 262 cxxtest = { 252 263 compile_settings = function() 253 264 add_default_include_paths("cxxtest") -
build/premake/premake4.lua
486 486 487 487 488 488 source_dirs = { 489 "lobby", 490 } 491 extern_libs = { 492 "spidermonkey", 493 "gloox", 494 } 495 setup_static_lib_project("lobby", source_dirs, extern_libs, {}) 496 497 498 source_dirs = { 489 499 "simulation2", 490 500 "simulation2/components", 491 501 "simulation2/helpers", … … 705 715 "libcurl", 706 716 707 717 "valgrind", 718 719 "gloox", 708 720 } 709 721 710 722 if not os.is("windows") and not _OPTIONS["android"] and not os.is("macosx") then -
source/ps/GameSetup/GameSetup.cpp
91 91 #include "network/NetServer.h" 92 92 #include "network/NetClient.h" 93 93 94 #include "lobby/XmppClient.h" 95 94 96 #include "ps/Pyrogenesis.h" // psSetLogDir 95 97 #include "ps/GameSetup/Atlas.h" 96 98 #include "ps/GameSetup/GameSetup.h" … … 653 655 { 654 656 EndGame(); 655 657 658 SAFE_DELETE(g_XmppClient); 659 656 660 ShutdownPs(); // Must delete g_GUI before g_ScriptingHost 657 661 658 662 in_reset_handlers(); … … 972 976 973 977 ogl_WarnIfError(); 974 978 979 if (args.Has("looping")) 980 { 981 InitPs(true, L"page_multiplayerlobby.xml", JSVAL_VOID); 982 return; 983 } 984 975 985 try 976 986 { 977 987 if (!Autostart(args)) -
source/gui/COList.h
1 #ifndef INCLUDED_COLIST 2 #define INCLUDED_COLIST 3 4 //-------------------------------------------------------- 5 // Includes / Compiler directives 6 //-------------------------------------------------------- 7 #include "GUI.h" 8 #include "CList.h" 9 10 //-------------------------------------------------------- 11 // Macros 12 //-------------------------------------------------------- 13 14 //-------------------------------------------------------- 15 // Types 16 //-------------------------------------------------------- 17 18 //-------------------------------------------------------- 19 // Declarations 20 //-------------------------------------------------------- 21 22 struct ObjectDef 23 { 24 CColor m_TextColor; 25 CStr m_Id; 26 int m_Width; 27 CStrW m_Heading; 28 29 }; 30 31 /** 32 * Todo : add description 33 * 34 */ 35 class COList : public CList 36 { 37 GUI_OBJECT(COList) 38 39 public: 40 COList(); 41 42 protected: 43 void SetupText(); 44 void HandleMessage(SGUIMessage &Message); 45 46 /** 47 * Handle the \<item\> tag. 48 */ 49 virtual bool HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile); 50 51 void DrawList(const int &selected, const CStr& _sprite, 52 const CStr& _sprite_selected, const CStr& _textcolor); 53 54 virtual CRect GetListRect() const { 55 return m_CachedActualSize + CRect(0, m_HeadingHeight, 0, 0); 56 57 CRect(m_CachedActualSize.left, 58 m_CachedActualSize.top+m_HeadingHeight, 59 m_CachedActualSize.right, 60 m_CachedActualSize.bottom); } 61 62 std::vector<ObjectDef> m_ObjectsDefs; 63 64 private: 65 float m_HeadingHeight; 66 67 }; 68 69 #endif // INCLUDED_COLIST -
source/gui/scripting/ScriptFunctions.cpp
43 43 #include "ps/UserReport.h" 44 44 #include "ps/GameSetup/Atlas.h" 45 45 #include "ps/GameSetup/Config.h" 46 #include "ps/ConfigDB.h" 46 47 #include "tools/atlas/GameInterface/GameLoop.h" 48 #include "lobby/XmppClient.h" 47 49 48 50 #include "simulation2/Simulation2.h" 49 51 #include "simulation2/components/ICmpAIManager.h" … … 556 558 g_Game->GetTurnManager()->RewindTimeWarp(); 557 559 } 558 560 561 /* Begin lobby related functions */ 562 563 void StartXmppClient(void* cbdata, std::string sUsername, std::string sPassword, std::string sRoom, std::string sNick) 564 { 565 CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata); 566 567 ENSURE(!g_XmppClient); 568 569 g_XmppClient = new XmppClient(guiManager->GetScriptInterface(), sUsername, sPassword, sRoom, sNick); 570 } 571 572 void StartRegisterXmppClient(void* cbdata, std::string sUsername, std::string sPassword) 573 { 574 CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata); 575 576 ENSURE(!g_XmppClient); 577 578 g_XmppClient = new XmppClient(guiManager->GetScriptInterface(), sUsername, sPassword, "", "", true); 579 } 580 581 void StopXmppClient(void* UNUSED(cbdata)) 582 { 583 ENSURE(g_XmppClient); 584 SAFE_DELETE(g_XmppClient); 585 } 586 587 void ConnectXmppClient(void* UNUSED(cbdata)) 588 { 589 ENSURE(g_XmppClient); 590 g_XmppClient->connect(); 591 } 592 593 void DisconnectXmppClient(void* UNUSED(cbdata)) 594 { 595 ENSURE(g_XmppClient); 596 g_XmppClient->disconnect(); 597 } 598 599 void RecvXmppClient(void* UNUSED(cbdata)) 600 { 601 if(!g_XmppClient) 602 return; 603 g_XmppClient->recv(); 604 } 605 606 void SendGetGameList(void* UNUSED(cbdata)) 607 { 608 if(!g_XmppClient) 609 return; 610 g_XmppClient->SendIqGetGameList(); 611 } 612 613 void SendRegisterGame(void* UNUSED(cbdata), CScriptVal data) 614 { 615 if(!g_XmppClient) 616 return; 617 g_XmppClient->SendIqRegisterGame(data); 618 } 619 620 void SendUnregisterGame(void* UNUSED(cbdata), std::string name) 621 { 622 if(!g_XmppClient) 623 return; 624 g_XmppClient->SendIqUnregisterGame(name); 625 } 626 627 CScriptVal GetPlayerList(void* UNUSED(cbdata)) 628 { 629 if(!g_XmppClient) 630 return CScriptVal(); 631 632 CScriptValRooted playerList = g_XmppClient->GUIGetPlayerList(); 633 634 return playerList.get(); 635 } 636 637 CScriptVal GetGameList(void* UNUSED(cbdata)) 638 { 639 if(!g_XmppClient) 640 return CScriptVal(); 641 642 CScriptValRooted gameList = g_XmppClient->GUIGetGameList(); 643 644 return gameList.get(); 645 } 646 647 CScriptVal LobbyGuiPollMessage(void* UNUSED(cbdata)) 648 { 649 if(!g_XmppClient) 650 return CScriptVal(); 651 652 CScriptValRooted poll = g_XmppClient->GuiPollMessage(); 653 654 return poll.get(); 655 } 656 657 void LobbySendMessage(void* UNUSED(cbdata), std::string message) 658 { 659 if(!g_XmppClient) 660 return; 661 662 g_XmppClient->SendMUCMessage(message); 663 } 664 665 std::string GetDefaultLobbyPlayerUsername(void* UNUSED(cbdata)) 666 { 667 std::string username; 668 CFG_GET_USER_VAL("lobby.login", String, username); 669 return username; 670 } 671 672 std::string GetDefaultLobbyPlayerPassword(void* UNUSED(cbdata)) 673 { 674 std::string password; 675 CFG_GET_USER_VAL("lobby.password", String, password); 676 return password; 677 } 678 679 void SetDefaultLobbyPlayerPair(void * UNUSED(cbdata), std::string username, std::string password) 680 { 681 g_ConfigDB.CreateValue(CFG_USER, "lobby.login")->m_String = username; 682 g_ConfigDB.CreateValue(CFG_USER, "lobby.password")->m_String = password; 683 g_ConfigDB.WriteFile(CFG_USER); 684 } 685 686 /* End lobby related functions */ 687 559 688 void QuickSave(void* UNUSED(cbdata)) 560 689 { 561 690 g_Game->GetTurnManager()->QuickSave(); … … 648 777 scriptInterface.RegisterFunction<void, unsigned int, &EnableTimeWarpRecording>("EnableTimeWarpRecording"); 649 778 scriptInterface.RegisterFunction<void, &RewindTimeWarp>("RewindTimeWarp"); 650 779 scriptInterface.RegisterFunction<void, bool, &SetBoundingBoxDebugOverlay>("SetBoundingBoxDebugOverlay"); 780 781 // Lobby functions 782 scriptInterface.RegisterFunction<void, std::string, std::string, std::string, std::string, &StartXmppClient>("StartXmppClient"); 783 scriptInterface.RegisterFunction<void, std::string, std::string, &StartRegisterXmppClient>("StartRegisterXmppClient"); 784 scriptInterface.RegisterFunction<void, &StopXmppClient>("StopXmppClient"); 785 scriptInterface.RegisterFunction<void, &ConnectXmppClient>("ConnectXmppClient"); 786 scriptInterface.RegisterFunction<void, &DisconnectXmppClient>("DisconnectXmppClient"); 787 scriptInterface.RegisterFunction<void, &RecvXmppClient>("RecvXmppClient"); 788 scriptInterface.RegisterFunction<void, &SendGetGameList>("SendGetGameList"); 789 scriptInterface.RegisterFunction<void, CScriptVal, &SendRegisterGame>("SendRegisterGame"); 790 scriptInterface.RegisterFunction<void, std::string, &SendUnregisterGame>("SendUnregisterGame"); 791 scriptInterface.RegisterFunction<CScriptVal, &GetPlayerList>("GetPlayerList"); 792 scriptInterface.RegisterFunction<CScriptVal, &GetGameList>("GetGameList"); 793 scriptInterface.RegisterFunction<CScriptVal, &LobbyGuiPollMessage>("LobbyGuiPollMessage"); 794 scriptInterface.RegisterFunction<void, std::string, &LobbySendMessage>("LobbySendMessage"); 795 scriptInterface.RegisterFunction<std::string, &GetDefaultLobbyPlayerUsername>("GetDefaultLobbyPlayerUsername"); 796 scriptInterface.RegisterFunction<std::string, &GetDefaultLobbyPlayerPassword>("GetDefaultLobbyPlayerPassword"); 797 scriptInterface.RegisterFunction<void, std::string, std::string, &SetDefaultLobbyPlayerPair>("SetDefaultLobbyPlayerPair"); 651 798 } -
source/gui/CList.h
86 86 * Sets up text, should be called every time changes has been 87 87 * made that can change the visual. 88 88 */ 89 v oid SetupText();89 virtual void SetupText(); 90 90 91 91 /** 92 92 * @see IGUIObject#HandleMessage() … … 121 121 122 122 // Extended drawing interface, this is so that classes built on the this one 123 123 // can use other sprite names. 124 v oid DrawList(const int &selected, const CStr& _sprite,124 virtual void DrawList(const int &selected, const CStr& _sprite, 125 125 const CStr& _sprite_selected, const CStr& _textcolor); 126 126 127 127 // Get the area of the list. This is so that i can easily be changed, like in CDropDown -
source/gui/CGUI.cpp
35 35 #include "CRadioButton.h" 36 36 #include "CInput.h" 37 37 #include "CList.h" 38 #include "COList.h" 38 39 #include "CDropDown.h" 39 40 #include "CProgressBar.h" 40 41 #include "CTooltip.h" … … 442 443 AddObjectType("minimap", &CMiniMap::ConstructObject); 443 444 AddObjectType("input", &CInput::ConstructObject); 444 445 AddObjectType("list", &CList::ConstructObject); 446 AddObjectType("olist", &COList::ConstructObject); 445 447 AddObjectType("dropdown", &CDropDown::ConstructObject); 446 448 AddObjectType("tooltip", &CTooltip::ConstructObject); 447 449 } -
source/gui/IGUIObject.h
424 424 * have any additional children (and this function should never be called). 425 425 */ 426 426 virtual bool HandleAdditionalChildren(const XMBElement& UNUSED(child), 427 427 CXeromyces* UNUSED(pFile)) { return false; } 428 428 429 429 /** 430 430 * Cached size, real size m_Size is actually dependent on resolution -
source/gui/COList.cpp
1 #include "COList.h" 2 3 #include "ps/CLogger.h" 4 5 COList::COList() : CList(),m_HeadingHeight(30.f) 6 { 7 AddSetting(GUIST_CGUISpriteInstance, "sprite_heading"); 8 } 9 10 void COList::SetupText() 11 { 12 if (!GetGUI()) 13 return; 14 15 CGUIList *pList; 16 GUI<CGUIList>::GetSettingPointer(this, "list_ip", pList); 17 18 //ENSURE(m_GeneratedTexts.size()>=1); 19 20 m_ItemsYPositions.resize( pList->m_Items.size()+1 ); 21 22 // Delete all generated texts. Some could probably be saved, 23 // but this is easier, and this function will never be called 24 // continuously, or even often, so it'll probably be okay. 25 std::vector<SGUIText*>::iterator it; 26 for (it=m_GeneratedTexts.begin(); it!=m_GeneratedTexts.end(); ++it) 27 { 28 if (*it) 29 delete *it; 30 } 31 m_GeneratedTexts.clear(); 32 33 CStrW font; 34 if (GUI<CStrW>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) 35 // Use the default if none is specified 36 // TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style. 37 font = L"default"; 38 39 //CGUIString caption; 40 bool scrollbar; 41 //GUI<CGUIString>::GetSetting(this, "caption", caption); 42 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 43 44 float width = GetListRect().GetWidth(); 45 // remove scrollbar if applicable 46 if (scrollbar && GetScrollBar(0).GetStyle()) 47 width -= GetScrollBar(0).GetStyle()->m_Width; 48 49 float buffer_zone=0.f; 50 GUI<float>::GetSetting(this, "buffer_zone", buffer_zone); 51 52 53 for (unsigned int c=0; c<m_ObjectsDefs.size(); ++c) 54 { 55 SGUIText *text = new SGUIText(); 56 CGUIString gui_string; 57 gui_string.SetValue(m_ObjectsDefs[c].m_Heading); 58 *text = GetGUI()->GenerateText(gui_string, font, width, buffer_zone, this); 59 AddText(text); 60 } 61 62 63 // Generate texts 64 float buffered_y = 0.f; 65 66 for (int i=0; i<(int)pList->m_Items.size(); ++i) 67 { 68 m_ItemsYPositions[i] = buffered_y; 69 for (unsigned int c=0; c<m_ObjectsDefs.size(); ++c) 70 { 71 CGUIList * pList_c; 72 GUI<CGUIList>::GetSettingPointer(this, m_ObjectsDefs[c].m_Id, pList_c); 73 SGUIText *text = new SGUIText(); 74 *text = GetGUI()->GenerateText(pList_c->m_Items[i], font, width, buffer_zone, this); 75 if (c==0) 76 buffered_y += text->m_Size.cy; 77 AddText(text); 78 } 79 } 80 81 m_ItemsYPositions[pList->m_Items.size()] = buffered_y; 82 83 //if (! scrollbar) 84 // CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]); 85 86 // Setup scrollbar 87 if (scrollbar) 88 { 89 GetScrollBar(0).SetScrollRange( m_ItemsYPositions.back() ); 90 GetScrollBar(0).SetScrollSpace( GetListRect().GetHeight() ); 91 92 CRect rect = GetListRect(); 93 GetScrollBar(0).SetX( rect.right ); 94 GetScrollBar(0).SetY( rect.top ); 95 GetScrollBar(0).SetZ( GetBufferedZ() ); 96 GetScrollBar(0).SetLength( rect.bottom - rect.top ); 97 } 98 } 99 100 void COList::HandleMessage(SGUIMessage &Message) 101 { 102 CList::HandleMessage(Message); 103 // switch (Message.type) 104 // { 105 // case GUIM_SETTINGS_UPDATED: 106 // if (Message.value.Find("list_") != -1) 107 // { 108 // SetupText(); 109 // } 110 // } 111 } 112 113 bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile) 114 { 115 int elmt_item = pFile->GetElementID("item"); 116 int elmt_heading = pFile->GetElementID("heading"); 117 int elmt_def = pFile->GetElementID("def"); 118 119 if (child.GetNodeName() == elmt_item) 120 { 121 AddItem(child.GetText().FromUTF8(), child.GetText().FromUTF8()); 122 return true; 123 } 124 else if (child.GetNodeName() == elmt_heading) 125 { 126 CStrW text (child.GetText().FromUTF8()); 127 128 return true; 129 } 130 else if (child.GetNodeName() == elmt_def) 131 { 132 ObjectDef oDef; 133 134 XMBAttributeList attributes = child.GetAttributes(); 135 for (int i=0; i<attributes.Count; ++i) 136 { 137 XMBAttribute attr = attributes.Item(i); 138 CStr attr_name (pFile->GetAttributeString(attr.Name)); 139 CStr attr_value (attr.Value); 140 141 if (attr_name == "color") 142 { 143 CColor color; 144 if (!GUI<CColor>::ParseString(attr_value.FromUTF8(), color)) 145 LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); 146 else oDef.m_TextColor = color; 147 } 148 else if (attr_name == "id") 149 { 150 oDef.m_Id = "list_"+attr_value; 151 } 152 else if (attr_name == "width") 153 { 154 int width; 155 if (!GUI<int>::ParseString(attr_value.FromUTF8(), width)) 156 LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); 157 else 158 oDef.m_Width = width; 159 } 160 else if (attr_name == "heading") 161 { 162 oDef.m_Heading = attr_value.FromUTF8(); 163 } 164 165 } 166 167 m_ObjectsDefs.push_back(oDef); 168 169 AddSetting(GUIST_CGUIList, oDef.m_Id); 170 SetupText(); 171 172 return true; 173 } 174 else 175 { 176 return false; 177 } 178 } 179 180 void COList::DrawList(const int &selected, 181 const CStr& _sprite, 182 const CStr& _sprite_selected, 183 const CStr& _textcolor) 184 { 185 float bz = GetBufferedZ(); 186 187 // First call draw on ScrollBarOwner 188 bool scrollbar; 189 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 190 191 if (scrollbar) 192 { 193 // Draw scrollbar 194 IGUIScrollBarOwner::Draw(); 195 } 196 197 if (GetGUI()) 198 { 199 CRect rect = GetListRect(); 200 201 CGUISpriteInstance *sprite=NULL, *sprite_selectarea=NULL; 202 int cell_id; 203 GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite, sprite); 204 GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite_selected, sprite_selectarea); 205 GUI<int>::GetSetting(this, "cell_id", cell_id); 206 207 CGUIList *pList; 208 GUI<CGUIList>::GetSettingPointer(this, "list_name", pList); 209 210 GetGUI()->DrawSprite(*sprite, cell_id, bz, rect); 211 212 float scroll=0.f; 213 if (scrollbar) 214 { 215 scroll = GetScrollBar(0).GetPos(); 216 } 217 218 if (selected != -1) 219 { 220 ENSURE(selected >= 0 && selected+1 < (int)m_ItemsYPositions.size()); 221 222 // Get rectangle of selection: 223 CRect rect_sel(rect.left, rect.top + m_ItemsYPositions[selected] - scroll, 224 rect.right, rect.top + m_ItemsYPositions[selected+1] - scroll); 225 226 if (rect_sel.top <= rect.bottom && 227 rect_sel.bottom >= rect.top) 228 { 229 if (rect_sel.bottom > rect.bottom) 230 rect_sel.bottom = rect.bottom; 231 if (rect_sel.top < rect.top) 232 rect_sel.top = rect.top; 233 234 if (scrollbar) 235 { 236 // Remove any overlapping area of the scrollbar. 237 if (rect_sel.right > GetScrollBar(0).GetOuterRect().left && 238 rect_sel.right <= GetScrollBar(0).GetOuterRect().right) 239 rect_sel.right = GetScrollBar(0).GetOuterRect().left; 240 241 if (rect_sel.left >= GetScrollBar(0).GetOuterRect().left && 242 rect_sel.left < GetScrollBar(0).GetOuterRect().right) 243 rect_sel.left = GetScrollBar(0).GetOuterRect().right; 244 } 245 246 GetGUI()->DrawSprite(*sprite_selectarea, cell_id, bz+0.05f, rect_sel); 247 } 248 } 249 250 CColor color; 251 GUI<CColor>::GetSetting(this, _textcolor, color); 252 253 CGUISpriteInstance *sprite_heading=NULL; 254 GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_heading", sprite_heading); 255 CRect rect_head(m_CachedActualSize.left, m_CachedActualSize.top, m_CachedActualSize.right, 256 m_CachedActualSize.top + m_HeadingHeight); 257 GetGUI()->DrawSprite(*sprite_heading, cell_id, bz, rect_head); 258 259 float xpos = 0; 260 for (unsigned int def=0; def< m_ObjectsDefs.size(); ++def) 261 { 262 DrawText(def, color, m_CachedActualSize.TopLeft() + CPos(xpos, 4), bz+0.1f, rect_head); 263 xpos += m_ObjectsDefs[def].m_Width; 264 } 265 266 for (int i=0; i<(int)pList->m_Items.size(); ++i) 267 { 268 if (m_ItemsYPositions[i+1] - scroll < 0 || 269 m_ItemsYPositions[i] - scroll > rect.GetHeight()) 270 continue; 271 272 // Clipping area (we'll have to substract the scrollbar) 273 CRect cliparea = GetListRect(); 274 275 if (scrollbar) 276 { 277 if (cliparea.right > GetScrollBar(0).GetOuterRect().left && 278 cliparea.right <= GetScrollBar(0).GetOuterRect().right) 279 cliparea.right = GetScrollBar(0).GetOuterRect().left; 280 281 if (cliparea.left >= GetScrollBar(0).GetOuterRect().left && 282 cliparea.left < GetScrollBar(0).GetOuterRect().right) 283 cliparea.left = GetScrollBar(0).GetOuterRect().right; 284 } 285 286 xpos = 0; 287 for (unsigned int def=0; def< m_ObjectsDefs.size(); ++def) 288 { 289 DrawText(m_ObjectsDefs.size() * (i+/*Heading*/1) + def, m_ObjectsDefs[def].m_TextColor, rect.TopLeft() + CPos(xpos, -scroll + m_ItemsYPositions[i]), bz+0.1f, cliparea); 290 xpos += m_ObjectsDefs[def].m_Width; 291 } 292 } 293 } 294 } -
source/tools/XpartaMuPP/XpartaMuPP.py
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 4 """ 5 XpartaMuPP by : 6 Badmadblacksad 7 .. 8 For : 0ad 9 License : GPL 10 """ 11 12 import sys 13 import logging 14 import time 15 from optparse import OptionParser 16 17 import sleekxmpp 18 from sleekxmpp.stanza import Iq 19 from sleekxmpp.stanza import * 20 from sleekxmpp.xmlstream import ElementBase, register_stanza_plugin, ET 21 from sleekxmpp.xmlstream.handler import Callback 22 from sleekxmpp.xmlstream.matcher import StanzaPath 23 24 from xml.dom.minidom import Document 25 26 ## Configuration ## 27 configDEMOModOn = False 28 ## !Configuration ## 29 30 class BasicGameList(ElementBase): 31 name = 'query' 32 namespace = 'jabber:iq:gamelist' 33 interfaces = set(('game', 'command')) 34 sub_interfaces = interfaces 35 plugin_attrib = 'gamelist' 36 37 def addGame(self, name, ip, mapName, mapSize, victoryCondition, nbp, tnbp): 38 itemXml = ET.Element("game", {"name":name, "ip":ip, "nbp":nbp, "tnbp":tnbp, "mapName":mapName, "mapSize":mapSize, "victoryCondition":victoryCondition}) 39 self.xml.append(itemXml) 40 41 def getGame(self): 42 game = self.xml.find('{%s}game' % self.namespace) 43 return game.get("name"), game.get("ip"), game.get("mapName"), game.get("mapSize"), game.get("victoryCondition"), game.get("nbp"), game.get("tnbp") 44 45 def getCommand(self): 46 command = self.xml.find('{%s}command' % self.namespace) 47 return command 48 49 class XpartaMuPP(sleekxmpp.ClientXMPP): 50 """ 51 A simple game list provider 52 """ 53 54 def __init__(self, sjid, password, room, nick): 55 sleekxmpp.ClientXMPP.__init__(self, sjid, password) 56 self.sjid = sjid 57 self.room = room 58 self.nick = nick 59 60 # Game management 61 self.m_gameList = {} 62 63 #DEMO 64 if configDEMOModOn: 65 self.addGame("666.666.666.666", "Unplayable map", "666.666.666.666", "Serengenti", "normal", "gold rush", "4", "4") 66 self.addGame("666.666.666.667", "Unreachale liberty", "666.666.666.667", "Oasis", "large", "conquest", "2", "4") 67 #for i in range(50): 68 # self.addGame("666.666.666."+str(i), "X"+str(i), "666.666.666."+str(i), "Oasis", "large", "conquest", "1", "4") 69 70 register_stanza_plugin(Iq, BasicGameList) 71 self.register_handler(Callback('Iq Gamelist', 72 StanzaPath('iq/gamelist'), 73 self.iqhandler, 74 instream=True)) 75 76 self.add_event_handler("session_start", self.start) 77 self.add_event_handler("message", self.message) 78 self.add_event_handler("muc::%s::got_online" % self.room, self.muc_online) 79 self.add_event_handler("muc::%s::got_offline" % self.room, self.muc_offline) 80 81 def start(self, event): 82 """ 83 Process the session_start event 84 """ 85 self.plugin['xep_0045'].joinMUC(self.room, self.nick) 86 87 self.send_presence() 88 self.get_roster() 89 logging.info("xpartamupp started") 90 91 #DEMO 92 self.DEMOrequestGameList() 93 #self.DEMOregisterGame() 94 95 def message(self, msg): 96 """ 97 Process incoming message stanzas 98 """ 99 if msg['type'] == 'chat': 100 msg.reply("Thanks for sending\n%(body)s" % msg).send() 101 logging.comm("receive message"+msg['body']) 102 103 def muc_online(self, presence): 104 """ 105 Process presence stanza from a chat room. 106 """ 107 if presence['muc']['nick'] != self.nick: 108 self.send_message(mto=presence['from'], mbody="Hello %s, welcome in the 0ad alpha chatroom. Polishes your weapons and get ready to fight!" %(presence['muc']['nick']), mtype='') 109 110 def muc_offline(self, presence): 111 """ 112 Process presence stanza from a chat room. 113 """ 114 if presence['muc']['nick'] != self.nick: 115 self.removeGame(presence['muc']['jid'].bare) 116 117 def iqhandler(self, iq): 118 """ 119 Handle the custom <gamelist> stanza 120 TODO: This method should be very robust because 121 we could receive anything 122 """ 123 if iq['type'] == 'error': 124 logging.error('iqhandler error' + iq['error']['condition']) 125 #self.disconnect() 126 elif iq['type'] == 'get': 127 """ 128 Request a gamelist 129 """ 130 self.sendGameList(iq['from']) 131 elif iq['type'] == 'result': 132 """ 133 Iq successfully received 134 """ 135 pass 136 elif iq['type'] == 'set': 137 """ 138 Register-update / unregister a game 139 """ 140 command = iq['gamelist']['command'].text 141 if command == 'register': 142 try: 143 name, ip, mapName, mapSize, victoryCondition, nbp, tnbp = iq['gamelist']['game'] 144 logging.debug("ip " + ip) 145 self.addGame(iq['from'].bare,name,ip,mapName,mapSize,victoryCondition,nbp,tnbp) 146 except: 147 logging.error("Failed to process game data") 148 elif command == 'unregister': 149 self.removeGame(iq['from'].bare) 150 151 def sendGameList(self, to): 152 """ 153 Send a massive stanza with the whole game list 154 """ 155 stz = BasicGameList() 156 for k in self.m_gameList: 157 g = self.m_gameList[k] 158 stz.addGame(g['name'], g['ip'], g['mapName'], g['mapSize'], g['victoryCondition'], g['nbp'], g['tnbp']) 159 iq = self.Iq() 160 iq['type'] = 'result' 161 iq['to'] = to 162 iq.setPayload(stz) 163 try: 164 iq.send() 165 except: 166 logging.error("Failed to send game list") 167 168 def DEMOrequestGameList(self): 169 """ 170 Test function 171 """ 172 iq = self.Iq() 173 iq['type'] = 'get' 174 iq['gamelist']['field'] = 'x' 175 iq['to'] = self.boundjid.full 176 iq.send(now=True, block=False) 177 return True 178 179 def DEMOregisterGame(self): 180 """ 181 Test function 182 """ 183 stz = BasicGameList() 184 stz.addGame("DEMOregister","DEMOip","DEMOmap","","","","") 185 stz['command'] = 'register' 186 iq = self.Iq() 187 iq['type'] = 'set' 188 iq['to'] = self.boundjid.full 189 iq.setPayload(stz) 190 iq.send(now=True, block=False) 191 return True 192 193 # Game management 194 195 def addGame(self, sid, name, ip, mapName, mapSize, victoryCondition, nbp, tnbp): 196 game = { 'name':name, 'ip':ip, 'nbp':nbp, 'tnbp':tnbp, 'mapName':mapName, 'mapSize':mapSize, 'victoryCondition':victoryCondition } 197 self.m_gameList[sid] = game 198 199 def removeGame(self, sid): 200 if sid in self.m_gameList: 201 del self.m_gameList[sid] 202 203 if __name__ == '__main__': 204 # Setup the command line arguments. 205 optp = OptionParser() 206 207 # Output verbosity options. 208 optp.add_option('-q', '--quiet', help='set logging to ERROR', 209 action='store_const', dest='loglevel', 210 const=logging.ERROR, default=logging.INFO) 211 optp.add_option('-d', '--debug', help='set logging to DEBUG', 212 action='store_const', dest='loglevel', 213 const=logging.DEBUG, default=logging.INFO) 214 optp.add_option('-v', '--verbose', help='set logging to COMM', 215 action='store_const', dest='loglevel', 216 const=5, default=logging.INFO) 217 218 # XpartaMuPP configuration options 219 optp.add_option('-m', '--domain', help='set xpartamupp domain', 220 action='store', dest='xdomain', 221 default="localhost") 222 optp.add_option('-l', '--login', help='set xpartamupp login', 223 action='store', dest='xlogin', 224 default="xpartamupp") 225 optp.add_option('-p', '--password', help='set xpartamupp password', 226 action='store', dest='xpassword', 227 default="XXXXXX") 228 optp.add_option('-n', '--nickname', help='set xpartamupp nickname', 229 action='store', dest='xnickname', 230 default="XpartaMuCC") 231 optp.add_option('-D', '--demo', help='set xpartamupp in DEMO mode (add a few fake games)', 232 action='store_true', dest='xdemomode', 233 default=False) 234 235 opts, args = optp.parse_args() 236 237 # Set DEMO mode 238 configDEMOModOn = opts.xdemomode 239 240 # Setup logging. 241 logging.basicConfig(level=opts.loglevel, 242 format='%(levelname)-8s %(message)s') 243 244 # XpartaMuPP 245 xmpp = XpartaMuPP(opts.xlogin+'@'+opts.xdomain+'/CC', opts.xpassword, 'arena@conference.'+opts.xdomain, opts.xnickname) 246 xmpp.register_plugin('xep_0030') # Service Discovery 247 xmpp.register_plugin('xep_0004') # Data Forms 248 xmpp.register_plugin('xep_0045') # Multi-User Chat # used 249 xmpp.register_plugin('xep_0060') # PubSub 250 xmpp.register_plugin('xep_0199') # XMPP Ping 251 252 if xmpp.connect(): 253 xmpp.process(threaded=False) 254 else: 255 logging.error("Unable to connect") 256 -
source/tools/XpartaMuPP/mod_ipstamp.erl
Property changes on: source/tools/XpartaMuPP/XpartaMuPP.py ___________________________________________________________________ Added: svn:executable + *
1 2 -module(mod_ipstamp). 3 4 -behaviour(gen_mod). 5 6 -include("ejabberd.hrl"). 7 8 -export([start/2, stop/1, on_filter_packet/1]). 9 10 start(_Host, _Opts) -> 11 ?INFO_MSG("mod_ipip starting", []), 12 ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 50), 13 ok. 14 15 stop(_Host) -> 16 ejabberd_hooks:delete(filter_packet, global, ?MODULE, on_filter_packet, 50), 17 ok. 18 19 on_filter_packet({From, To, Packet} = Input) -> 20 {_,STo,_,_,_,_,_} = To, 21 if STo == "xpartamupp" -> 22 {_,SElement,LPacketInfo,LPacketQuery} = Packet, 23 if SElement == "iq" -> 24 {_, SType} = lists:keyfind("type",1,LPacketInfo), 25 if SType == "set" -> 26 {_,_,LXmlns,LGame} = lists:keyfind("query",2,LPacketQuery), 27 {_,SXmlns} = lists:keyfind("xmlns",1,LXmlns), 28 if SXmlns == "jabber:iq:gamelist" -> 29 {_,_,_,LCommand} = lists:keyfind("command",2,LGame), 30 {_,SCommand} = lists:keyfind(xmlcdata,1,LCommand), 31 if SCommand == <<"register">> -> 32 {_,_,KGame,_} = lists:keyfind("game",2,LGame), 33 Info = ejabberd_sm:get_user_info("xpartamupp","localhost","CC"), 34 {ip, {Ploc, _Port}} = lists:keyfind(ip, 1, Info), 35 SIp = inet_parse:ntoa(Ploc), 36 ?INFO_MSG(string:concat("stamp ip: ",SIp), []), 37 {From,To,{xmlelement,"iq",LPacketInfo,[ 38 {xmlelement,"query",[{"xmlns","jabber:iq:gamelist"}],[ 39 {xmlelement,"game",lists:keyreplace("ip",1,KGame,{"ip",SIp}),[]}, 40 {xmlelement,"command",[],[{xmlcdata,<<"register">>}]} 41 ] 42 } 43 ]}} 44 ; true -> Input 45 end 46 ; true -> Input 47 end 48 ; true -> Input 49 end 50 ; true -> Input 51 end 52 ; true -> Input 53 end. 54 -
source/tools/XpartaMuPP/Makefile
1 include_dir = /usr/lib/ejabberd/include/ 2 ebin_dir = /usr/lib/ejabberd/ebin/ 3 4 module = mod_ipstamp.beam 5 all : ${module} 6 7 %.beam : %.erl 8 erlc -I ${include_dir} -pz ${ebin_dir} $< 9 10 install : 11 mv ${module} ${ebin_dir} 12 13 clean : 14 rm ${module} 15 16 restart : 17 rm -f /var/log/ejabberd/ejabberd.log 18 /etc/init.d/ejabberd restart -
source/tools/XpartaMuPP/README
1 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2 @@ Install ejabberd and the erlang compiler @@ 3 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4 # apt-get install ejabberd erlang-dev? 5 6 Configure it 7 # dpkg-reconfigure ejabberd 8 set the domain name (e.g. localhost if you installed it on your development computer) 9 and a login / password 10 11 You should now be able to connect to this XMPP server using a normal XMPP client (e.g. Empathy). 12 13 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14 @@ Installation of the custom XMPP module @@ 15 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 16 Go to it's source directory 17 $ cd source/tools/XpartaMuPP 18 19 Build and install it 20 $ make 21 # make install 22 23 Tell ejabberd that you want it to load the module 24 In /etc/ejabberd/ejabberd.cfg, add {mod_ipstamp, []} 25 in the Modules list "Modules enabled in all ejabberd virtual hosts" 26 27 Restart ejabberd 28 # service ejabberd restart 29 30 If something goes wrong read /var/log/ejabberd/ejabberd.log 31 32 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 33 @@ Ejabberd administration @@ 34 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 35 Go http://localhost:5280/admin and connect 36 (the login looks like login@domain (e.g. adminjabber@localhost)) 37 38 In "Acces rules" check that "register" is set to "[{allow,all}]" 39 40 You can see the list of registered / connected users in 41 "Virtual Hosts" >> domain name >> "users" 42 43 You must manually add a new user for XpartaMuPP. 44 Enter a login (use "xpartamupp" since that's what clients expect) 45 and password, then press "Add user" 46 47 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 48 @@ Run XpartaMuPP - XMPP Multiplayer Game Manager @@ 49 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 50 You need to have python 3 installed 51 $ sudo apt-get install python3 52 53 You also need the SleekXmpp Python library 54 Go to to github and follow their instructions 55 https://github.com/fritzy/SleekXMPP 56 57 Then execute the following command to run the script with default options 58 $ ./source/tools/XpartaMuPP.py 59 60 or rather a similar command to run a properly configured program 61 $ ./source/tools/XpartaMuPP.py --domain localhost --login xpartamupp --password XXXXXX --nickname XpartaMuCC 62 63 Run ./source/tools/XpartaMuPP.py -h for the full list of options 64 65 If everything is fine you should see something along these lines in your console 66 <<<< 67 INFO Negotiating TLS 68 INFO Using SSL version: 3 69 INFO Node set to: xpartamupp@localhost/CC 70 xpartamupp started 71 <<<< 72 73 Congratulations, you are running XpartaMuPP - the 0ad Multiplayer Game Manager. 74 -
source/lobby/XmppClient.cpp
1 #include "precompiled.h" 2 #include "XmppClient.h" 3 #include "GameItemData.h" 4 5 //debug 6 #include <iostream> 7 8 #include <sstream> 9 10 //Gloox 11 #include <gloox/rostermanager.h> 12 #include <gloox/rosteritem.h> 13 #include <gloox/error.h> 14 15 //Game - script 16 #include "scriptinterface/ScriptInterface.h" 17 18 //Configuration 19 #include "ps/ConfigDB.h" 20 21 //global 22 XmppClient *g_XmppClient = NULL; 23 24 //debug 25 #if 1 26 #define DbgXMPP(x) 27 #else 28 #define DbgXMPP(x) std::cout << x << std::endl; 29 #endif 30 31 //utils 32 std::string StanzaErrorToString(StanzaError& err) 33 { 34 std::string msg; 35 #define CASE(X, Y) case X: return Y; 36 switch (err) 37 { 38 CASE(StanzaErrorBadRequest, "Bad request") 39 CASE(StanzaErrorConflict, "Player name already used") 40 CASE(StanzaErrorFeatureNotImplemented, "Feature not implemented") 41 CASE(StanzaErrorForbidden, "Forbidden") 42 CASE(StanzaErrorGone, "Recipient or server gone") 43 CASE(StanzaErrorInternalServerError, "Internal server error") 44 CASE(StanzaErrorItemNotFound, "Item not found") 45 CASE(StanzaErrorJidMalformed, "Jid malformed") 46 CASE(StanzaErrorNotAcceptable, "Not acceptable") 47 CASE(StanzaErrorNotAllowed, "Not allowed") 48 CASE(StanzaErrorNotAuthorized, "Not authorized") 49 CASE(StanzaErrorNotModified, "Not modified") 50 CASE(StanzaErrorPaymentRequired, "Payment required") 51 CASE(StanzaErrorRecipientUnavailable, "Recipient unavailable") 52 CASE(StanzaErrorRedirect, "Redirect") 53 CASE(StanzaErrorRegistrationRequired, "Registration required") 54 CASE(StanzaErrorRemoteServerNotFound, "Remote server not found") 55 CASE(StanzaErrorRemoteServerTimeout, "Remote server timeout") 56 CASE(StanzaErrorResourceConstraint, "Resource constraint") 57 CASE(StanzaErrorServiceUnavailable, "Service unavailable") 58 CASE(StanzaErrorSubscribtionRequired, "Subscribtion Required") 59 CASE(StanzaErrorUndefinedCondition, "Undefined condition") 60 CASE(StanzaErrorUnexpectedRequest, "Unexpected request") 61 CASE(StanzaErrorUnknownSender, "Unknown sender") 62 default: 63 return "Error undefined"; 64 } 65 #undef CASE 66 } 67 68 XmppClient::XmppClient(ScriptInterface& scriptInterface, std::string sUsername, std::string sPassword, std::string sRoom, std::string sNick, bool regOpt) 69 : m_ScriptInterface(scriptInterface), _client(NULL), _mucRoom(NULL), _registration(NULL), _username(sUsername), _password(sPassword), _nick(sNick) 70 { 71 // Read lobby configuration from default.cfg 72 std::string sServer; 73 std::string sXpartamupp; 74 CFG_GET_USER_VAL("lobby.server", String, sServer); 75 CFG_GET_USER_VAL("lobby.xpartamupp", String, sXpartamupp); 76 77 _xpartamuppId = sXpartamupp+std::string("@")+sServer+std::string("/CC"); 78 JID clientJid(sUsername+std::string("@")+sServer+std::string("/0ad")); 79 JID roomJid(sRoom+std::string("@conference.")+sServer+std::string("/")+sNick); 80 81 // If we are connecting, use the full jid and a password 82 // If we are registering, only use the server name 83 if(!regOpt) 84 _client = new Client(clientJid, sPassword); 85 else 86 _client = new Client(sServer); 87 88 _client->registerConnectionListener( this ); 89 _client->setPresence(Presence::Available, -1); 90 _client->disco()->setVersion( "TestProg", "1.0" ); 91 _client->disco()->setIdentity( "client", "bot" ); 92 _client->setCompression(false); 93 94 _client->registerStanzaExtension( new GameListQuery() ); 95 _client->registerIqHandler( this, ExtGameListQuery); 96 97 _client->registerMessageHandler( this ); 98 99 StringList ca; 100 ca.push_back( "/path/to/cacert.crt" ); 101 _client->setCACerts( ca ); 102 103 // Uncomment to see the raw stanzas 104 //_client->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this ); 105 106 if (!regOpt) 107 { 108 // Create a Multi User Chat Room 109 _mucRoom = new MUCRoom(_client, roomJid, this, 0); 110 // Disable the history because its anoying 111 _mucRoom->setRequestHistory(0, MUCRoom::HistoryMaxStanzas); 112 } 113 else 114 { 115 // Registration 116 _registration = new Registration( _client ); 117 _registration->registerRegistrationHandler( this ); 118 } 119 } 120 121 XmppClient::~XmppClient() 122 { 123 DbgXMPP("XmppClient destroyed"); 124 delete _registration; 125 delete _mucRoom; 126 delete _client; 127 } 128 129 // Game - script 130 ScriptInterface& XmppClient::GetScriptInterface() 131 { 132 return m_ScriptInterface; 133 } 134 135 //Network 136 void XmppClient::connect() 137 { 138 _client->connect(false); 139 } 140 141 void XmppClient::disconnect() 142 { 143 _client->disconnect(); 144 } 145 146 void XmppClient::recv() 147 { 148 _client->recv(1); 149 } 150 151 /* 152 * MUC Handlers 153 */ 154 void XmppClient::handleMUCParticipantPresence(gloox::MUCRoom*, gloox::MUCRoomParticipant participant, const gloox::Presence& presence) 155 { 156 //std::string jid = participant.jid->full(); 157 std::string nick = participant.nick->resource(); 158 gloox::Presence::PresenceType presenceType = presence.presence(); 159 if (presenceType == Presence::Unavailable) 160 { 161 DbgXMPP(nick << " left the room"); 162 m_PlayerMap.erase(nick); 163 } 164 else 165 { 166 DbgXMPP(nick << " is in the room"); 167 m_PlayerMap[nick] = std::pair<std::string, int>(nick, (int)presenceType); 168 } 169 CreateSimpleMessage("system", "playerlist updated", "internal"); 170 } 171 172 void XmppClient::handleMUCMessage( MUCRoom*, const Message& msg, bool ) 173 { 174 DbgXMPP(msg.from().resource() << " said " << msg.body()); 175 std::string nick = msg.from().resource(); 176 std::string body = msg.body(); 177 178 CScriptValRooted message; 179 GetScriptInterface().Eval("({ 'type':'mucmessage'})", message); 180 GetScriptInterface().SetProperty(message.get(), "from", nick); 181 GetScriptInterface().SetProperty(message.get(), "text", body); 182 PushGuiMessage(message); 183 } 184 185 void XmppClient::handleMUCError(gloox::MUCRoom*, gloox::StanzaError err) 186 { 187 std::string msg = StanzaErrorToString(err); 188 CreateSimpleMessage("system", msg, "error"); 189 } 190 191 void XmppClient::handleMUCItems( MUCRoom * /*room*/, const Disco::ItemList& items ) 192 { 193 m_PlayerMap.clear(); 194 195 // Add the received items 196 Disco::ItemList::const_iterator it = items.begin(); 197 for( ; it != items.end(); ++it ) 198 { 199 std::string jid = (*it)->jid().full().c_str(); 200 std::string nick = (*it)->name().c_str(); 201 m_PlayerMap[nick] = std::pair<std::string, int>(nick, Presence::Available); 202 //printf( "%s -- %s is an item here\n", (*it)->jid().full().c_str(), (*it)->name().c_str() ); 203 } 204 CreateSimpleMessage("system", "playerlist updated", "internal"); 205 } 206 207 /* 208 * Log (debug) Handler 209 */ 210 void XmppClient::handleLog( LogLevel level, LogArea area, const std::string& message ) 211 { 212 std::cout << "log: level: " << level << ", area: " << area << ", message: " << message << std::endl; 213 } 214 215 /* 216 * IQ Handler 217 */ 218 bool XmppClient::handleIq( const IQ& iq ) 219 { 220 DbgXMPP("handleIq [" << iq.tag()->xml() << "]"); 221 222 if(iq.subtype() == gloox::IQ::Result) 223 { 224 const GameListQuery* q = iq.findExtension<GameListQuery>( ExtGameListQuery ); 225 if(q) 226 { 227 m_GameList.clear(); 228 std::list<GameItemData*>::const_iterator it = q->gameList().begin(); 229 for(; it != q->gameList().end(); ++it) 230 { 231 m_GameList.push_back(**it); 232 } 233 CreateSimpleMessage("system", "gamelist updated", "internal"); 234 } 235 } 236 else if(iq.subtype() == gloox::IQ::Error) 237 { 238 StanzaError err = iq.error()->error(); 239 std::string msg = StanzaErrorToString(err); 240 CreateSimpleMessage("system", msg, "error"); 241 } 242 else 243 { 244 CreateSimpleMessage("system", std::string("unknown subtype : ") + iq.tag()->name(), "error"); 245 } 246 247 return true; 248 } 249 250 /* 251 * Connection Handlers 252 */ 253 void XmppClient::onConnect() 254 { 255 if (_mucRoom) 256 { 257 CreateSimpleMessage("system", "connected"); 258 _mucRoom->join(); 259 //_mucRoom->getRoomInfo(); 260 _mucRoom->getRoomItems(); 261 SendIqGetGameList(); 262 } 263 264 if (_registration) 265 { 266 _registration->fetchRegistrationFields(); 267 } 268 } 269 270 void XmppClient::onDisconnect( ConnectionError e ) 271 { 272 // Make sure we properly leave the room so than 273 // everything work if we decide to come back later 274 if (_mucRoom) 275 _mucRoom->leave(); 276 277 if( e == ConnAuthenticationFailed ) 278 CreateSimpleMessage("system", "authentication failed", "error"); 279 else 280 CreateSimpleMessage("system", "disconnected"); 281 282 m_PlayerMap.clear(); 283 m_GameList.clear(); 284 CreateSimpleMessage("system", "playerlist updated", "internal"); 285 CreateSimpleMessage("system", "gamelist updated", "internal"); 286 } 287 288 bool XmppClient::onTLSConnect( const CertInfo& ) 289 { 290 return true; 291 } 292 293 /* 294 * Requests 295 */ 296 297 /* Request GameList from cloud */ 298 void XmppClient::SendIqGetGameList() 299 { 300 JID xpartamuppJid(_xpartamuppId); 301 302 // Send IQ 303 IQ iq(gloox::IQ::Get, xpartamuppJid); 304 iq.addExtension( new GameListQuery() ); 305 DbgXMPP("SendIqGetGameList [" << iq.tag()->xml() << "]"); 306 _client->send(iq); 307 } 308 309 /* Register a game */ 310 void XmppClient::SendIqRegisterGame(CScriptVal data) 311 { 312 JID xpartamuppJid(_xpartamuppId); 313 314 std::string name, mapName, mapSize, victoryCondition, nbp, tnbp; 315 GetScriptInterface().GetProperty(data.get(), "name", name); 316 GetScriptInterface().GetProperty(data.get(), "mapName", mapName); 317 GetScriptInterface().GetProperty(data.get(), "mapSize", mapSize); 318 GetScriptInterface().GetProperty(data.get(), "victoryCondition", victoryCondition); 319 GetScriptInterface().GetProperty(data.get(), "nbp", nbp); 320 GetScriptInterface().GetProperty(data.get(), "tnbp", tnbp); 321 322 // Send IQ 323 GameListQuery* g = new GameListQuery(); 324 g->m_command = "register"; 325 /* This "x" fake ip will be overwritten by the ip stamp XMPP module */ 326 GameItemData *pItemData = new GameItemData(name, "x"); 327 pItemData->m_mapName = mapName; 328 pItemData->m_mapSize = mapSize; 329 pItemData->m_victoryCondition = victoryCondition; 330 pItemData->m_nbp = nbp; 331 pItemData->m_tnbp = tnbp; 332 g->m_gameList.push_back( pItemData ); 333 334 IQ iq(gloox::IQ::Set, xpartamuppJid); 335 iq.addExtension( g ); 336 DbgXMPP("SendIqRegisterGame [" << iq.tag()->xml() << "]"); 337 _client->send(iq); 338 } 339 340 /* Unregister a game */ 341 void XmppClient::SendIqUnregisterGame(std::string name) 342 { 343 JID xpartamuppJid(_xpartamuppId); 344 345 // Send IQ 346 GameListQuery* g = new GameListQuery(); 347 g->m_command = "unregister"; 348 g->m_gameList.push_back( new GameItemData(name) ); 349 350 IQ iq(gloox::IQ::Set, xpartamuppJid); 351 iq.addExtension( g ); 352 DbgXMPP("SendIqUnregisterGame [" << iq.tag()->xml() << "]"); 353 _client->send(iq); 354 } 355 356 /* 357 * Registration 358 */ 359 void XmppClient::handleRegistrationFields( const JID& /*from*/, int fields, std::string ) 360 { 361 RegistrationFields vals; 362 vals.username = _username; 363 vals.password = _password; 364 _registration->createAccount( fields, vals ); 365 } 366 367 void XmppClient::handleRegistrationResult( const JID& /*from*/, RegistrationResult result ) 368 { 369 if (result == gloox::RegistrationSuccess) 370 { 371 CreateSimpleMessage("system", "Registered"); 372 } 373 else 374 { 375 std::string msg; 376 #define CASE(X, Y) case X: msg = Y; break; 377 switch(result) 378 { 379 CASE(RegistrationNotAcceptable, "Registration not acceptable") 380 CASE(RegistrationConflict, "Registration conflict") 381 CASE(RegistrationNotAuthorized, "Registration not authorized") 382 CASE(RegistrationBadRequest, "Registration bad request") 383 CASE(RegistrationForbidden, "Registration forbidden") 384 CASE(RegistrationRequired, "Registration required") 385 CASE(RegistrationUnexpectedRequest, "Registration unexpected request") 386 CASE(RegistrationNotAllowed, "Registration not allowed") 387 default: msg = "Registration unknown error"; 388 } 389 #undef CASE 390 CreateSimpleMessage("system", msg, "error"); 391 } 392 disconnect(); 393 } 394 395 void XmppClient::handleAlreadyRegistered( const JID& /*from*/ ) 396 { 397 DbgXMPP("the account already exists"); 398 } 399 400 void XmppClient::handleDataForm( const JID& /*from*/, const DataForm& /*form*/ ) 401 { 402 DbgXMPP("dataForm received"); 403 } 404 405 void XmppClient::handleOOB( const JID& /*from*/, const OOB& /* oob */ ) 406 { 407 DbgXMPP("OOB registration requested"); 408 } 409 410 /** 411 * Message 412 */ 413 void XmppClient::handleMessage( const Message& msg, MessageSession * /*session*/ ) 414 { 415 DbgXMPP("type " << msg.subtype() << ", subject " << msg.subject().c_str() 416 << ", message " << msg.body().c_str() << ", thread id " << msg.thread().c_str()); 417 418 std::string nick = msg.from().resource(); 419 std::string body = msg.body(); 420 421 CScriptValRooted message; 422 GetScriptInterface().Eval("({ 'type':'message'})", message); 423 GetScriptInterface().SetProperty(message.get(), "from", nick); 424 GetScriptInterface().SetProperty(message.get(), "text", body); 425 PushGuiMessage(message); 426 } 427 428 429 430 /* Requests from GUI */ 431 CScriptValRooted XmppClient::GUIGetPlayerList() 432 { 433 CScriptValRooted playerList; 434 GetScriptInterface().Eval("({})", playerList); 435 for(std::map<std::string, std::pair<std::string, int> >::iterator it = m_PlayerMap.begin(); it != m_PlayerMap.end(); ++it) 436 { 437 CScriptValRooted player; 438 GetScriptInterface().Eval("({})", player); 439 GetScriptInterface().SetProperty(player.get(), "name", it->second.first.c_str()); 440 GetScriptInterface().SetProperty(player.get(), "presenceType", it->second.first); 441 442 GetScriptInterface().SetProperty(playerList.get(), it->second.first.c_str(), player); 443 } 444 445 return playerList; 446 } 447 448 CScriptValRooted XmppClient::GUIGetGameList() 449 { 450 CScriptValRooted gameList; 451 GetScriptInterface().Eval("({})", gameList); 452 for(std::list<GameItemData>::iterator it = m_GameList.begin(); it !=m_GameList.end(); ++it) 453 { 454 CScriptValRooted game; 455 GetScriptInterface().Eval("({})", game); 456 457 #define ITEM(param)\ 458 GetScriptInterface().SetProperty(game.get(), #param, it->m_##param .c_str()); 459 ITEMS 460 #undef ITEM 461 462 GetScriptInterface().SetProperty(gameList.get(), it->m_name.c_str(), game); 463 } 464 465 return gameList; 466 } 467 468 /* Messages */ 469 CScriptValRooted XmppClient::GuiPollMessage() 470 { 471 if (m_GuiMessageQueue.empty()) 472 return CScriptValRooted(); 473 474 CScriptValRooted r = m_GuiMessageQueue.front(); 475 m_GuiMessageQueue.pop_front(); 476 return r; 477 } 478 479 void XmppClient::SendMUCMessage(std::string message) 480 { 481 _mucRoom->send(message); 482 } 483 484 void XmppClient::PushGuiMessage(const CScriptValRooted& message) 485 { 486 ENSURE(!message.undefined()); 487 488 m_GuiMessageQueue.push_back(message); 489 } 490 491 void XmppClient::CreateSimpleMessage(std::string type, std::string text, std::string level) 492 { 493 CScriptValRooted message; 494 GetScriptInterface().Eval("({})", message); 495 GetScriptInterface().SetProperty(message.get(), "type", type); 496 GetScriptInterface().SetProperty(message.get(), "level", level); 497 GetScriptInterface().SetProperty(message.get(), "text", text); 498 PushGuiMessage(message); 499 } 500 501 /* 502 * GameListQuery, custom IQ Stanza 503 */ 504 505 GameListQuery::GameListQuery( const Tag* tag ) 506 : StanzaExtension( ExtGameListQuery ) 507 { 508 if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_GAMELIST ) 509 return; 510 511 const Tag* c = tag->findTag( "query/game" ); 512 if (c) 513 m_command = c->cdata(); 514 515 const ConstTagList& l = tag->findTagList( "query/game" ); 516 ConstTagList::const_iterator it = l.begin(); 517 for( ; it != l.end(); ++it ) 518 { 519 GameItemData *pItem = new GameItemData(); 520 #define ITEM(param)\ 521 const std::string param = (*it)->findAttribute( #param ); \ 522 pItem->m_##param = param; 523 ITEMS 524 #undef ITEM 525 m_gameList.push_back( pItem ); 526 } 527 } 528 529 GameListQuery::~GameListQuery() 530 { 531 util::clearList( m_gameList ); 532 } 533 534 const std::string& GameListQuery::filterString() const 535 { 536 static const std::string filter = "/iq/query[@xmlns='" + XMLNS_GAMELIST + "']"; 537 return filter; 538 } 539 540 Tag* GameListQuery::tag() const 541 { 542 Tag* t = new Tag( "query" ); 543 t->setXmlns( XMLNS_GAMELIST ); 544 /* 545 RosterData::const_iterator it = m_roster.begin(); 546 for( ; it != m_roster.end(); ++it ) 547 t->addChild( (*it)->tag() ); 548 */ 549 550 // register / unregister command 551 if(!m_command.empty()) 552 t->addChild(new Tag("command", m_command)); 553 554 std::list<GameItemData*>::const_iterator it = m_gameList.begin(); 555 for( ; it != m_gameList.end(); ++it ) 556 t->addChild( (*it)->tag() ); 557 558 return t; 559 } 560 561 StanzaExtension* GameListQuery::clone() const 562 { 563 GameListQuery* q = new GameListQuery(); 564 565 return q; 566 } 567 568 const std::list<GameItemData*>& GameListQuery::gameList() const 569 { 570 return m_gameList; 571 } -
source/lobby/GameItemData.h
1 #ifndef GAMEITEMDATA_H 2 #define GAMEITEMDATA_H 3 4 #include <string> 5 6 #define ITEMS \ 7 ITEM(name) \ 8 ITEM(ip) \ 9 ITEM(nbp) \ 10 ITEM(tnbp) \ 11 ITEM(mapName) \ 12 ITEM(mapSize) \ 13 ITEM(victoryCondition) 14 15 class GameItemData 16 { 17 friend class XmppClient; 18 friend class GameListQuery; 19 public: 20 GameItemData(std::string name= "", std::string ip = "") 21 : m_name(name), m_ip(ip) 22 { 23 } 24 25 virtual ~GameItemData() {} 26 27 Tag* tag() const 28 { 29 Tag* i = new Tag( "game" ); 30 31 #define ITEM(param)\ 32 i->addAttribute( #param, m_##param ); 33 ITEMS 34 #undef ITEM 35 36 return i; 37 } 38 39 protected: 40 #define ITEM(param)\ 41 std::string m_##param ; 42 ITEMS 43 #undef ITEM 44 }; 45 46 #endif -
source/lobby/XmppClient.h
1 #ifndef XXXMPPCLIENT_H 2 #define XXXMPPCLIENT_H 3 4 //network 5 #include <gloox/jid.h> 6 #include <gloox/client.h> 7 #include <gloox/mucroom.h> 8 #include <gloox/message.h> 9 10 #include <gloox/messagehandler.h> 11 #include <gloox/presencehandler.h> 12 #include <gloox/mucroomhandler.h> 13 #include <gloox/loghandler.h> 14 #include <gloox/connectionlistener.h> 15 #include <gloox/registration.h> 16 17 #include <gloox/iq.h> 18 #include <gloox/iqhandler.h> 19 20 //game - script 21 #include <deque> 22 #include "scriptinterface/ScriptVal.h" 23 24 //Global Gamelist Extension 25 #define ExtGameListQuery 1403 26 const std::string XMLNS_GAMELIST = "jabber:iq:gamelist"; 27 28 //debug 29 using namespace gloox; 30 31 //Game - script 32 class ScriptInterface; 33 class GameItemData; 34 35 class XmppClient : public ConnectionListener, public MUCRoomHandler, public IqHandler, public LogHandler, public RegistrationHandler, public MessageHandler 36 { 37 private: 38 //Game - script 39 ScriptInterface& m_ScriptInterface; 40 //Components 41 Client* _client; 42 MUCRoom* _mucRoom; 43 Registration* _registration; 44 //Account infos 45 std::string _username; 46 std::string _password; 47 std::string _nick; 48 std::string _xpartamuppId; 49 50 public: 51 //Basic 52 XmppClient(ScriptInterface& scriptInterface, std::string sUsername, std::string sPassword, std::string sRoom, std::string sNick, bool regOpt = false); 53 virtual ~XmppClient(); 54 55 //Network 56 void connect(); 57 void disconnect(); 58 void recv(); 59 void SendIqGetGameList(); 60 void SendIqRegisterGame(CScriptVal data); 61 void SendIqUnregisterGame(std::string name); 62 63 CScriptValRooted GUIGetPlayerList(); 64 CScriptValRooted GUIGetGameList(); 65 66 //Script 67 ScriptInterface& GetScriptInterface(); 68 69 protected: 70 /* Xmpp handlers */ 71 /* MUC handlers */ 72 virtual void handleMUCParticipantPresence(gloox::MUCRoom*, gloox::MUCRoomParticipant, const gloox::Presence&); 73 virtual bool handleMUCRoomCreation(gloox::MUCRoom*) {return false;} 74 virtual void handleMUCSubject(gloox::MUCRoom*, const std::string&, const std::string&) {} 75 virtual void handleMUCInviteDecline(gloox::MUCRoom*, const gloox::JID&, const std::string&) {} 76 virtual void handleMUCError(gloox::MUCRoom*, gloox::StanzaError); 77 virtual void handleMUCInfo(gloox::MUCRoom*, int, const std::string&, const gloox::DataForm*) {} 78 virtual void handleMUCItems(gloox::MUCRoom*, const std::list<gloox::Disco::Item*, std::allocator<gloox::Disco::Item*> >&); 79 virtual void handleMUCMessage( MUCRoom* room, const Message& msg, bool priv ); 80 81 /* Log handler */ 82 virtual void handleLog( LogLevel level, LogArea area, const std::string& message ); 83 84 /* ConnectionListener handlers*/ 85 virtual void onConnect(); 86 virtual void onDisconnect( ConnectionError e ); 87 virtual bool onTLSConnect( const CertInfo& info ); 88 89 /* Iq Handlers */ 90 virtual bool handleIq( const IQ& iq ); 91 virtual void handleIqID( const IQ&, int ) {} 92 93 /* Registration Handlers */ 94 virtual void handleRegistrationFields( const JID& /*from*/, int fields, std::string instructions ); 95 virtual void handleRegistrationResult( const JID& /*from*/, RegistrationResult result ); 96 virtual void handleAlreadyRegistered( const JID& /*from*/ ); 97 virtual void handleDataForm( const JID& /*from*/, const DataForm& /*form*/ ); 98 virtual void handleOOB( const JID& /*from*/, const OOB& oob ); 99 100 /* Message Handler */ 101 virtual void handleMessage( const Message& msg, MessageSession * session ); 102 103 /* Messages */ 104 public: 105 CScriptValRooted GuiPollMessage(); 106 void SendMUCMessage(std::string message); 107 protected: 108 void PushGuiMessage(const CScriptValRooted& message); 109 void CreateSimpleMessage(std::string type, std::string text, std::string level = "standard"); 110 111 private: 112 /// Map of players 113 std::map<std::string, std::pair<std::string, int> > m_PlayerMap; 114 /// List of games 115 std::list< GameItemData > m_GameList; 116 /// Queue of messages 117 std::deque<CScriptValRooted> m_GuiMessageQueue; 118 }; 119 120 class GameListQuery : public StanzaExtension 121 { 122 friend class XmppClient; 123 public: 124 GameListQuery( const Tag* tag = 0 ); 125 126 ~GameListQuery(); 127 128 // reimplemented from StanzaExtension 129 virtual const std::string& filterString() const; 130 131 // reimplemented from StanzaExtension 132 virtual StanzaExtension* newInstance( const Tag* tag ) const 133 { 134 return new GameListQuery( tag ); 135 } 136 137 // reimplemented from StanzaExtension 138 virtual Tag* tag() const; 139 140 // reimplemented from StanzaExtension 141 virtual StanzaExtension* clone() const; 142 143 const std::list<GameItemData*>& gameList() const; 144 145 private: 146 std::string m_command; 147 std::list<GameItemData*> m_gameList; 148 }; 149 150 extern XmppClient *g_XmppClient; 151 152 #endif // XMPPCLIENT_H -
source/lobby/makefile
1 2 .PHONY = all 3 4 all: main 5 flags= -g 6 7 XmppClient.o : XmppClient.cpp XmppClient.h 8 g++ $(flags) -c XmppClient.cpp 9 10 main.o : main.cpp 11 g++ $(flags) -c main.cpp 12 13 main : XmppClient.o main.o 14 g++ $(flags) -o $@ XmppClient.o main.o -lgloox -lpthread -
source/pch/lobby/precompiled.cpp
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "precompiled.h" -
source/pch/lobby/precompiled.h
1 /* Copyright (C) 2009 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "lib/precompiled.h" // common precompiled header -
binaries/data/mods/public/gui/pregame/mainmenu.xml
196 196 Matches 197 197 <action on="Press"> 198 198 closeMenu(); 199 Engine.PushGuiPage("page_gamesetup.xml", { type: "offline" });199 Engine.PushGuiPage("page_gamesetup.xml", { type: "offline", source: "mainmenu" }); 200 200 </action> 201 201 </object> 202 202 … … 253 253 <action on="Press"> 254 254 closeMenu(); 255 255 // Open Multiplayer connection window with join option. 256 Engine.PushGuiPage("page_gamesetup_mp.xml", "join");256 Engine.PushGuiPage("page_gamesetup_mp.xml", { multiplayerGameType: "join", source: "mainmenu" }); 257 257 </action> 258 258 </object> 259 259 … … 268 268 <action on="Press"> 269 269 closeMenu(); 270 270 // Open Multiplayer connection window with host option. 271 Engine.PushGuiPage("page_gamesetup_mp.xml", "host");271 Engine.PushGuiPage("page_gamesetup_mp.xml", { multiplayerGameType: "host", source: "mainmenu" }); 272 272 </action> 273 273 </object> 274 </object>275 274 275 <object name="subMenuMultiplayerLobbyButton" 276 type="button" 277 style="StoneButtonFancy" 278 size="0 64 100% 92" 279 tooltip_style="pgToolTip" 280 tooltip="Launch the multiplayer lobby." 281 > 282 Game Lobby 283 <action on="Press"> 284 closeMenu(); 285 // Open Multiplayer game lobby. 286 Engine.PushGuiPage("page_prelobby.xml", []); 287 </action> 288 </object> 289 </object> 290 276 291 <!-- submenuToolsAndOptions --> 277 292 <object name="submenuToolsAndOptions" 278 293 type="image" … … 402 417 Multiplayer 403 418 <action on="Press"> 404 419 closeMenu(); 405 openMenu("submenuMultiplayer", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 2);420 openMenu("submenuMultiplayer", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 3); 406 421 </action> 407 422 </object> 408 423 -
binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js
1 1 var g_IsConnecting = false; 2 2 var g_GameType; // "server" or "client" 3 var g_Source; // "mainmenu" or "lobby" 4 var g_ServerName = ""; 5 var g_Name; 6 var g_Ip; 3 7 4 8 var g_IsRejoining = false; 5 9 var g_GameAttributes; // used when rejoining 6 10 var g_PlayerAssignments; // used when rejoining 7 11 8 function init( multiplayerGameType)12 function init(attribs) 9 13 { 10 switch (multiplayerGameType) 14 switch (attribs.multiplayerGameType) 15 { 16 case "join": 17 getGUIObjectByName("pageJoin").hidden = false; 18 getGUIObjectByName("pageHost").hidden = true; 19 break; 20 case "host": 21 getGUIObjectByName("pageJoin").hidden = true; 22 getGUIObjectByName("pageHost").hidden = false; 23 break; 24 default: 25 error("Unrecognised multiplayer game type : " + attribs.multiplayerGameType); 26 break; 27 } 28 29 switch (attribs.source) 11 30 { 12 case "join": 13 getGUIObjectByName("pageJoin").hidden = false; 14 getGUIObjectByName("pageHost").hidden = true; 15 break; 16 case "host": 17 getGUIObjectByName("pageJoin").hidden = true; 18 getGUIObjectByName("pageHost").hidden = false; 19 break; 20 default: 21 error("Unrecognised multiplayer game type : " + multiplayerGameType); 22 break; 31 case "mainmenu": 32 g_Source = "mainmenu"; 33 break; 34 case "lobby": 35 g_Source = "lobby"; 36 getGUIObjectByName("hostServerNameWrapper").hidden = false; 37 break; 38 default: 39 error("Unrecognised source : " + attribs.source); 23 40 } 41 42 if (attribs.name) 43 { 44 getGUIObjectByName("hostPlayerName").caption = attribs.name; 45 getGUIObjectByName("joinPlayerName").caption = attribs.name; 46 } 47 if (attribs.ip) getGUIObjectByName("joinIP").caption = attribs.ip; 24 48 } 25 49 26 50 function cancelSetup() 27 51 { 28 52 if (g_IsConnecting) 29 53 Engine.DisconnectNetworkGame(); 30 Engine.PopGuiPage(); 54 Engine.PopGuiPage(); 31 55 } 32 56 33 57 function startConnectionStatus(type) … … 43 67 if (!g_IsConnecting) 44 68 return; 45 69 70 pollAndHandleNetworkClient(); 71 } 72 73 function pollAndHandleNetworkClient() 74 { 46 75 while (true) 47 76 { 48 77 var message = Engine.PollNetworkClient(); … … 119 148 else 120 149 { 121 150 Engine.PopGuiPage(); 122 Engine.PushGuiPage("page_gamesetup.xml", { "type": g_GameType });151 Engine.PushGuiPage("page_gamesetup.xml", { "type": g_GameType, "source": g_Source, "serverName": g_ServerName }); 123 152 return; // don't process any more messages - leave them for the game GUI loop 124 153 } 125 154 … … 163 192 } 164 193 165 194 startConnectionStatus("server"); 166 // TODO: ought to do something(?) with servername195 g_ServerName = servername; 167 196 168 197 return true; 169 198 } -
binaries/data/mods/public/gui/gamesetup/gamesetup.js
19 19 // Is this user in control of game settings (i.e. is a network server, or offline player) 20 20 var g_IsController; 21 21 22 // Where this user come from ("mainmenu" or "lobby") 23 var g_Source; 24 25 //Server name, if user is a server, connected to the multiplayer lobby 26 var g_ServerName; 27 22 28 // Are we currently updating the GUI in response to network messages instead of user input 23 29 // (and therefore shouldn't send further messages to the network) 24 30 var g_IsInGuiUpdate; … … 69 75 default: 70 76 error("Unexpected 'type' in gamesetup init: "+attribs.type); 71 77 } 78 79 switch (attribs.source) 80 { 81 case "mainmenu": 82 g_Source = "mainmenu"; 83 break; 84 case "lobby": 85 g_Source = "lobby"; 86 break; 87 default: 88 error("Unrecognised source : " + attribs.source); 89 } 90 91 if (attribs.serverName) 92 g_ServerName = attribs.serverName; 72 93 } 73 94 74 95 // Called after the map data is loaded and cached … … 156 177 updateGameAttributes(); 157 178 } 158 179 }; 180 mapSize.selected = 0; 159 181 160 182 getGUIObjectByName("revealMap").onPress = function() 161 183 { // Update attributes so other players can see change … … 281 303 { 282 304 case "disconnected": 283 305 Engine.DisconnectNetworkGame(); 306 if (isServerOnLobby()) Engine.SendUnregisterGame(g_ServerName); 284 307 Engine.PopGuiPage(); 285 308 reportDisconnect(message.reason); 286 309 break; … … 322 345 break; 323 346 324 347 case "start": 348 if (g_Source == "lobby") Engine.StopXmppClient(); 325 349 Engine.SwitchGuiPage("page_loading.xml", { 326 350 "attribs": g_GameAttributes, 327 351 "isNetworked" : g_IsNetworked, … … 508 532 getGUIObjectByName("setupWindow").hidden = false; 509 533 initMain(); 510 534 g_LoadingState++; 535 if (isServerOnLobby()) 536 { 537 sendRegisterGameStanza(); 538 } 511 539 } 512 540 else if (g_LoadingState == 2) 513 541 { … … 942 970 if (g_IsNetworked) 943 971 { 944 972 Engine.SetNetworkGameAttributes(g_GameAttributes); 973 if (isServerOnLobby() && g_LoadingState >= 2) 974 { 975 sendRegisterGameStanza(); 976 } 945 977 } 946 978 else 947 979 { … … 1259 1291 } 1260 1292 return false; 1261 1293 } 1294 1295 function isServerOnLobby() 1296 { 1297 return (g_IsController && g_Source == "lobby") ? true : false; 1298 } 1299 1300 function sendRegisterGameStanza() 1301 { 1302 var selectedMapSize = getGUIObjectByName("mapSize").selected; 1303 var selectedVictoryCondition = getGUIObjectByName("victoryCondition").selected; 1304 1305 var mapSize = getGUIObjectByName("mapSize").list[selectedMapSize]; 1306 var victoryCondition = getGUIObjectByName("victoryCondition").list[selectedVictoryCondition]; 1307 var nbp = "x"; 1308 var tnbp = "X"; 1309 1310 gameData = { 1311 "name":g_ServerName, 1312 "mapName":g_GameAttributes.map, 1313 "mapSize":mapSize, 1314 "victoryCondition":victoryCondition, 1315 "nbp":nbp, 1316 "tnbp":tnbp 1317 }; 1318 Engine.SendRegisterGame(gameData); 1319 } -
binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml
72 72 ]]></action> 73 73 </object> 74 74 75 <object hidden="true"> <!-- TODO: restore this when the server name is actually used -->75 <object name="hostServerNameWrapper" hidden="true"> 76 76 <object type="text" size="0 80 200 110" style="RightLabelText"> 77 77 Server name: 78 78 </object> -
binaries/data/mods/public/gui/gamesetup/gamesetup.xml
240 240 style="StoneButton" 241 241 size="100%-164 100%-52 100%-24 100%-24" 242 242 tooltip_style="onscreenToolTip" 243 tooltip="Return to the main menu."244 243 > 245 Main menu 244 <action on="Load"><![CDATA[ 245 if(!isServerOnLobby) 246 { 247 this.caption = "Main menu"; 248 this.tooltip = "Return to the main menu." 249 } 250 else 251 { 252 this.caption = "Quit"; 253 this.tooltip = "Return to the lobby." 254 } 255 ]]></action> 246 256 <action on="Press"> 247 257 <![CDATA[ 248 258 cancelSetup(); 259 if(isServerOnLobby()) Engine.SendUnregisterGame(g_ServerName); 249 260 Engine.PopGuiPage(); 250 261 ]]> 251 262 </action> -
binaries/data/mods/public/gui/page_lobby.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <page> 3 <include>common/setup.xml</include> 4 <include>common/styles.xml</include> 5 <include>common/sprite1.xml</include> 6 7 <include>common/common_sprites.xml</include> 8 <include>common/common_styles.xml</include> 9 10 <include>lobby/styles.xml</include> 11 <include>lobby/lobby.xml</include> 12 </page> -
binaries/data/mods/public/gui/page_prelobby.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <page> 3 <include>common/setup.xml</include> 4 <include>common/styles.xml</include> 5 <include>common/sprite1.xml</include> 6 7 <include>common/common_sprites.xml</include> 8 <include>common/common_styles.xml</include> 9 10 <include>gamesetup/styles.xml</include> 11 <include>summary/sprites.xml</include> 12 <include>lobby/prelobby.xml</include> 13 </page> 14 -
binaries/data/config/default.cfg
237 237 joystick.camera.rotate.y = 2 238 238 joystick.camera.zoom.in = 5 239 239 joystick.camera.zoom.out = 4 240 241 ; Multiplayer lobby preferences 242 lobby.server = "localhost" 243 lobby.xpartamupp = "xpartamupp"