Ticket #1504: 0ad-multiplayer-lobby-v30-06-2012bis.diff
File 0ad-multiplayer-lobby-v30-06-2012bis.diff, 69.0 KB (added by , 12 years ago) |
---|
-
build/premake/extern_libs4.lua
252 252 }) 253 253 end, 254 254 }, 255 gloox = { 256 compile_settings = function() 257 add_default_include_paths("gloox") 258 end, 259 link_settings = function() 260 if os.is("windows") then 261 add_default_lib_paths("gloox") 262 end 263 add_default_links({ 264 win_names = { "gloox-1.0" }, 265 unix_names = { "gloox" }, 266 }) 267 end, 268 }, 255 269 cxxtest = { 256 270 compile_settings = function() 257 271 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 "boost", 495 } 496 setup_static_lib_project("lobby", source_dirs, extern_libs, {}) 497 498 499 source_dirs = { 489 500 "simulation2", 490 501 "simulation2/components", 491 502 "simulation2/helpers", … … 705 716 "libcurl", 706 717 707 718 "valgrind", 719 720 "gloox", 708 721 } 709 722 710 723 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", "Serengeti", "128", "gold rush", "4", "4") 66 self.addGame("666.666.666.667", "Unreachale liberty", "666.666.666.667", "oasis", "256", "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 #include "precompiled.h" 5 6 //debug 7 #include <iostream> 8 9 //Gloox 10 #include <gloox/rostermanager.h> 11 #include <gloox/rosteritem.h> 12 #include <gloox/error.h> 13 14 //Game - script 15 #include "scriptinterface/ScriptInterface.h" 16 17 //Configuration 18 #include "ps/ConfigDB.h" 19 20 using namespace gloox; 21 22 //global 23 XmppClient *g_XmppClient = NULL; 24 25 //debug 26 #if 1 27 #define DbgXMPP(x) 28 #else 29 #define DbgXMPP(x) std::cout << x << std::endl; 30 #endif 31 32 //utils 33 std::string StanzaErrorToString(StanzaError& err) 34 { 35 std::string msg; 36 #define CASE(X, Y) case X: return Y; 37 switch (err) 38 { 39 CASE(StanzaErrorBadRequest, "Bad request") 40 CASE(StanzaErrorConflict, "Player name already used") 41 CASE(StanzaErrorFeatureNotImplemented, "Feature not implemented") 42 CASE(StanzaErrorForbidden, "Forbidden") 43 CASE(StanzaErrorGone, "Recipient or server gone") 44 CASE(StanzaErrorInternalServerError, "Internal server error") 45 CASE(StanzaErrorItemNotFound, "Item not found") 46 CASE(StanzaErrorJidMalformed, "Jid malformed") 47 CASE(StanzaErrorNotAcceptable, "Not acceptable") 48 CASE(StanzaErrorNotAllowed, "Not allowed") 49 CASE(StanzaErrorNotAuthorized, "Not authorized") 50 CASE(StanzaErrorNotModified, "Not modified") 51 CASE(StanzaErrorPaymentRequired, "Payment required") 52 CASE(StanzaErrorRecipientUnavailable, "Recipient unavailable") 53 CASE(StanzaErrorRedirect, "Redirect") 54 CASE(StanzaErrorRegistrationRequired, "Registration required") 55 CASE(StanzaErrorRemoteServerNotFound, "Remote server not found") 56 CASE(StanzaErrorRemoteServerTimeout, "Remote server timeout") 57 CASE(StanzaErrorResourceConstraint, "Resource constraint") 58 CASE(StanzaErrorServiceUnavailable, "Service unavailable") 59 CASE(StanzaErrorSubscribtionRequired, "Subscribtion Required") 60 CASE(StanzaErrorUndefinedCondition, "Undefined condition") 61 CASE(StanzaErrorUnexpectedRequest, "Unexpected request") 62 CASE(StanzaErrorUnknownSender, "Unknown sender") 63 default: 64 return "Error undefined"; 65 } 66 #undef CASE 67 } 68 69 XmppClient::XmppClient(ScriptInterface& scriptInterface, std::string sUsername, std::string sPassword, std::string sRoom, std::string sNick, bool regOpt) 70 : m_ScriptInterface(scriptInterface), _client(NULL), _mucRoom(NULL), _registration(NULL), _username(sUsername), _password(sPassword), _nick(sNick) 71 { 72 // Read lobby configuration from default.cfg 73 std::string sServer; 74 std::string sXpartamupp; 75 CFG_GET_USER_VAL("lobby.server", String, sServer); 76 CFG_GET_USER_VAL("lobby.xpartamupp", String, sXpartamupp); 77 78 _xpartamuppId = sXpartamupp+std::string("@")+sServer+std::string("/CC"); 79 JID clientJid(sUsername+std::string("@")+sServer+std::string("/0ad")); 80 JID roomJid(sRoom+std::string("@conference.")+sServer+std::string("/")+sNick); 81 82 // If we are connecting, use the full jid and a password 83 // If we are registering, only use the server name 84 if(!regOpt) 85 _client = new Client(clientJid, sPassword); 86 else 87 _client = new Client(sServer); 88 89 _client->registerConnectionListener( this ); 90 _client->setPresence(Presence::Available, -1); 91 _client->disco()->setVersion( "TestProg", "1.0" ); 92 _client->disco()->setIdentity( "client", "bot" ); 93 _client->setCompression(false); 94 95 _client->registerStanzaExtension( new GameListQuery() ); 96 _client->registerIqHandler( this, ExtGameListQuery); 97 98 _client->registerMessageHandler( this ); 99 100 StringList ca; 101 ca.push_back( "/path/to/cacert.crt" ); 102 _client->setCACerts( ca ); 103 104 // Uncomment to see the raw stanzas 105 //_client->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this ); 106 107 if (!regOpt) 108 { 109 // Create a Multi User Chat Room 110 _mucRoom = new MUCRoom(_client, roomJid, this, 0); 111 // Disable the history because its anoying 112 _mucRoom->setRequestHistory(0, MUCRoom::HistoryMaxStanzas); 113 } 114 else 115 { 116 // Registration 117 _registration = new Registration( _client ); 118 _registration->registerRegistrationHandler( this ); 119 } 120 } 121 122 XmppClient::~XmppClient() 123 { 124 DbgXMPP("XmppClient destroyed"); 125 delete _registration; 126 delete _mucRoom; 127 delete _client; 128 } 129 130 // Game - script 131 ScriptInterface& XmppClient::GetScriptInterface() 132 { 133 return m_ScriptInterface; 134 } 135 136 //Network 137 void XmppClient::connect() 138 { 139 _client->connect(false); 140 } 141 142 void XmppClient::disconnect() 143 { 144 _client->disconnect(); 145 } 146 147 void XmppClient::recv() 148 { 149 _client->recv(1); 150 } 151 152 /* 153 * MUC Handlers 154 */ 155 void XmppClient::handleMUCParticipantPresence(gloox::MUCRoom*, gloox::MUCRoomParticipant participant, const gloox::Presence& presence) 156 { 157 //std::string jid = participant.jid->full(); 158 std::string nick = participant.nick->resource(); 159 gloox::Presence::PresenceType presenceType = presence.presence(); 160 if (presenceType == Presence::Unavailable) 161 { 162 DbgXMPP(nick << " left the room"); 163 m_PlayerMap.erase(nick); 164 } 165 else 166 { 167 DbgXMPP(nick << " is in the room"); 168 m_PlayerMap[nick] = std::pair<std::string, int>(nick, (int)presenceType); 169 } 170 CreateSimpleMessage("system", "playerlist updated", "internal"); 171 } 172 173 void XmppClient::handleMUCMessage( MUCRoom*, const Message& msg, bool ) 174 { 175 DbgXMPP(msg.from().resource() << " said " << msg.body()); 176 std::string nick = msg.from().resource(); 177 std::string body = msg.body(); 178 179 CScriptValRooted message; 180 GetScriptInterface().Eval("({ 'type':'mucmessage'})", message); 181 GetScriptInterface().SetProperty(message.get(), "from", nick); 182 GetScriptInterface().SetProperty(message.get(), "text", body); 183 PushGuiMessage(message); 184 } 185 186 void XmppClient::handleMUCError(gloox::MUCRoom*, gloox::StanzaError err) 187 { 188 std::string msg = StanzaErrorToString(err); 189 CreateSimpleMessage("system", msg, "error"); 190 } 191 192 void XmppClient::handleMUCItems( MUCRoom * /*room*/, const Disco::ItemList& items ) 193 { 194 m_PlayerMap.clear(); 195 196 // Add the received items 197 Disco::ItemList::const_iterator it = items.begin(); 198 for( ; it != items.end(); ++it ) 199 { 200 std::string jid = (*it)->jid().full().c_str(); 201 std::string nick = (*it)->name().c_str(); 202 m_PlayerMap[nick] = std::pair<std::string, int>(nick, Presence::Available); 203 //printf( "%s -- %s is an item here\n", (*it)->jid().full().c_str(), (*it)->name().c_str() ); 204 } 205 CreateSimpleMessage("system", "playerlist updated", "internal"); 206 } 207 208 /* 209 * Log (debug) Handler 210 */ 211 void XmppClient::handleLog( LogLevel level, LogArea area, const std::string& message ) 212 { 213 std::cout << "log: level: " << level << ", area: " << area << ", message: " << message << std::endl; 214 } 215 216 /* 217 * IQ Handler 218 */ 219 bool XmppClient::handleIq( const IQ& iq ) 220 { 221 DbgXMPP("handleIq [" << iq.tag()->xml() << "]"); 222 223 if(iq.subtype() == gloox::IQ::Result) 224 { 225 const GameListQuery* q = iq.findExtension<GameListQuery>( ExtGameListQuery ); 226 if(q) 227 { 228 m_GameList.clear(); 229 std::list<GameItemData*>::const_iterator it = q->gameList().begin(); 230 for(; it != q->gameList().end(); ++it) 231 { 232 m_GameList.push_back(**it); 233 } 234 CreateSimpleMessage("system", "gamelist updated", "internal"); 235 } 236 } 237 else if(iq.subtype() == gloox::IQ::Error) 238 { 239 StanzaError err = iq.error()->error(); 240 std::string msg = StanzaErrorToString(err); 241 CreateSimpleMessage("system", msg, "error"); 242 } 243 else 244 { 245 CreateSimpleMessage("system", std::string("unknown subtype : ") + iq.tag()->name(), "error"); 246 } 247 248 return true; 249 } 250 251 /* 252 * Connection Handlers 253 */ 254 void XmppClient::onConnect() 255 { 256 if (_mucRoom) 257 { 258 CreateSimpleMessage("system", "connected"); 259 _mucRoom->join(); 260 //_mucRoom->getRoomInfo(); 261 _mucRoom->getRoomItems(); 262 SendIqGetGameList(); 263 } 264 265 if (_registration) 266 { 267 _registration->fetchRegistrationFields(); 268 } 269 } 270 271 void XmppClient::onDisconnect( ConnectionError e ) 272 { 273 // Make sure we properly leave the room so than 274 // everything work if we decide to come back later 275 if (_mucRoom) 276 _mucRoom->leave(); 277 278 if( e == ConnAuthenticationFailed ) 279 CreateSimpleMessage("system", "authentication failed", "error"); 280 else 281 CreateSimpleMessage("system", "disconnected"); 282 283 m_PlayerMap.clear(); 284 m_GameList.clear(); 285 CreateSimpleMessage("system", "playerlist updated", "internal"); 286 CreateSimpleMessage("system", "gamelist updated", "internal"); 287 } 288 289 bool XmppClient::onTLSConnect( const CertInfo& ) 290 { 291 return true; 292 } 293 294 /* 295 * Requests 296 */ 297 298 /* Request GameList from cloud */ 299 void XmppClient::SendIqGetGameList() 300 { 301 JID xpartamuppJid(_xpartamuppId); 302 303 // Send IQ 304 IQ iq(gloox::IQ::Get, xpartamuppJid); 305 iq.addExtension( new GameListQuery() ); 306 DbgXMPP("SendIqGetGameList [" << iq.tag()->xml() << "]"); 307 _client->send(iq); 308 } 309 310 /* Register a game */ 311 void XmppClient::SendIqRegisterGame(CScriptVal data) 312 { 313 JID xpartamuppJid(_xpartamuppId); 314 315 std::string name, mapName, mapSize, victoryCondition, nbp, tnbp; 316 GetScriptInterface().GetProperty(data.get(), "name", name); 317 GetScriptInterface().GetProperty(data.get(), "mapName", mapName); 318 GetScriptInterface().GetProperty(data.get(), "mapSize", mapSize); 319 GetScriptInterface().GetProperty(data.get(), "victoryCondition", victoryCondition); 320 GetScriptInterface().GetProperty(data.get(), "nbp", nbp); 321 GetScriptInterface().GetProperty(data.get(), "tnbp", tnbp); 322 323 // Send IQ 324 GameListQuery* g = new GameListQuery(); 325 g->m_command = "register"; 326 /* This "x" fake ip will be overwritten by the ip stamp XMPP module */ 327 GameItemData *pItemData = new GameItemData(name, "x"); 328 pItemData->m_mapName = mapName; 329 pItemData->m_mapSize = mapSize; 330 pItemData->m_victoryCondition = victoryCondition; 331 pItemData->m_nbp = nbp; 332 pItemData->m_tnbp = tnbp; 333 g->m_gameList.push_back( pItemData ); 334 335 IQ iq(gloox::IQ::Set, xpartamuppJid); 336 iq.addExtension( g ); 337 DbgXMPP("SendIqRegisterGame [" << iq.tag()->xml() << "]"); 338 _client->send(iq); 339 } 340 341 /* Unregister a game */ 342 void XmppClient::SendIqUnregisterGame(std::string name) 343 { 344 JID xpartamuppJid(_xpartamuppId); 345 346 // Send IQ 347 GameListQuery* g = new GameListQuery(); 348 g->m_command = "unregister"; 349 g->m_gameList.push_back( new GameItemData(name) ); 350 351 IQ iq(gloox::IQ::Set, xpartamuppJid); 352 iq.addExtension( g ); 353 DbgXMPP("SendIqUnregisterGame [" << iq.tag()->xml() << "]"); 354 _client->send(iq); 355 } 356 357 /* 358 * Registration 359 */ 360 void XmppClient::handleRegistrationFields( const JID& /*from*/, int fields, std::string ) 361 { 362 RegistrationFields vals; 363 vals.username = _username; 364 vals.password = _password; 365 _registration->createAccount( fields, vals ); 366 } 367 368 void XmppClient::handleRegistrationResult( const JID& /*from*/, RegistrationResult result ) 369 { 370 if (result == gloox::RegistrationSuccess) 371 { 372 CreateSimpleMessage("system", "Registered"); 373 } 374 else 375 { 376 std::string msg; 377 #define CASE(X, Y) case X: msg = Y; break; 378 switch(result) 379 { 380 CASE(RegistrationNotAcceptable, "Registration not acceptable") 381 CASE(RegistrationConflict, "Registration conflict") 382 CASE(RegistrationNotAuthorized, "Registration not authorized") 383 CASE(RegistrationBadRequest, "Registration bad request") 384 CASE(RegistrationForbidden, "Registration forbidden") 385 CASE(RegistrationRequired, "Registration required") 386 CASE(RegistrationUnexpectedRequest, "Registration unexpected request") 387 CASE(RegistrationNotAllowed, "Registration not allowed") 388 default: msg = "Registration unknown error"; 389 } 390 #undef CASE 391 CreateSimpleMessage("system", msg, "error"); 392 } 393 disconnect(); 394 } 395 396 void XmppClient::handleAlreadyRegistered( const JID& /*from*/ ) 397 { 398 DbgXMPP("the account already exists"); 399 } 400 401 void XmppClient::handleDataForm( const JID& /*from*/, const DataForm& /*form*/ ) 402 { 403 DbgXMPP("dataForm received"); 404 } 405 406 void XmppClient::handleOOB( const JID& /*from*/, const OOB& /* oob */ ) 407 { 408 DbgXMPP("OOB registration requested"); 409 } 410 411 /** 412 * Message 413 */ 414 void XmppClient::handleMessage( const Message& msg, MessageSession * /*session*/ ) 415 { 416 DbgXMPP("type " << msg.subtype() << ", subject " << msg.subject().c_str() 417 << ", message " << msg.body().c_str() << ", thread id " << msg.thread().c_str()); 418 419 std::string nick = msg.from().resource(); 420 std::string body = msg.body(); 421 422 CScriptValRooted message; 423 GetScriptInterface().Eval("({ 'type':'message'})", message); 424 GetScriptInterface().SetProperty(message.get(), "from", nick); 425 GetScriptInterface().SetProperty(message.get(), "text", body); 426 PushGuiMessage(message); 427 } 428 429 430 431 /* Requests from GUI */ 432 CScriptValRooted XmppClient::GUIGetPlayerList() 433 { 434 CScriptValRooted playerList; 435 GetScriptInterface().Eval("({})", playerList); 436 for(std::map<std::string, std::pair<std::string, int> >::iterator it = m_PlayerMap.begin(); it != m_PlayerMap.end(); ++it) 437 { 438 CScriptValRooted player; 439 GetScriptInterface().Eval("({})", player); 440 GetScriptInterface().SetProperty(player.get(), "name", it->second.first.c_str()); 441 GetScriptInterface().SetProperty(player.get(), "presenceType", it->second.first); 442 443 GetScriptInterface().SetProperty(playerList.get(), it->second.first.c_str(), player); 444 } 445 446 return playerList; 447 } 448 449 CScriptValRooted XmppClient::GUIGetGameList() 450 { 451 CScriptValRooted gameList; 452 //GetScriptInterface().Eval("({})", gameList); 453 GetScriptInterface().Eval("([])", gameList); 454 for(std::list<GameItemData>::iterator it = m_GameList.begin(); it !=m_GameList.end(); ++it) 455 { 456 CScriptValRooted game; 457 GetScriptInterface().Eval("({})", game); 458 459 #define ITEM(param)\ 460 GetScriptInterface().SetProperty(game.get(), #param, it->m_##param .c_str()); 461 ITEMS 462 #undef ITEM 463 464 //GetScriptInterface().SetProperty(gameList.get(), it->m_name.c_str(), game); 465 GetScriptInterface().CallFunctionVoid(gameList.get(), "push", game); 466 } 467 468 return gameList; 469 } 470 471 /* Messages */ 472 CScriptValRooted XmppClient::GuiPollMessage() 473 { 474 if (m_GuiMessageQueue.empty()) 475 return CScriptValRooted(); 476 477 CScriptValRooted r = m_GuiMessageQueue.front(); 478 m_GuiMessageQueue.pop_front(); 479 return r; 480 } 481 482 void XmppClient::SendMUCMessage(std::string message) 483 { 484 _mucRoom->send(message); 485 } 486 487 void XmppClient::PushGuiMessage(const CScriptValRooted& message) 488 { 489 ENSURE(!message.undefined()); 490 491 m_GuiMessageQueue.push_back(message); 492 } 493 494 void XmppClient::CreateSimpleMessage(std::string type, std::string text, std::string level) 495 { 496 CScriptValRooted message; 497 GetScriptInterface().Eval("({})", message); 498 GetScriptInterface().SetProperty(message.get(), "type", type); 499 GetScriptInterface().SetProperty(message.get(), "level", level); 500 GetScriptInterface().SetProperty(message.get(), "text", text); 501 PushGuiMessage(message); 502 } 503 504 /* 505 * GameListQuery, custom IQ Stanza 506 */ 507 508 GameListQuery::GameListQuery( const Tag* tag ) 509 : StanzaExtension( ExtGameListQuery ) 510 { 511 if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_GAMELIST ) 512 return; 513 514 const Tag* c = tag->findTag( "query/game" ); 515 if (c) 516 m_command = c->cdata(); 517 518 const ConstTagList& l = tag->findTagList( "query/game" ); 519 ConstTagList::const_iterator it = l.begin(); 520 for( ; it != l.end(); ++it ) 521 { 522 GameItemData *pItem = new GameItemData(); 523 #define ITEM(param)\ 524 const std::string param = (*it)->findAttribute( #param ); \ 525 pItem->m_##param = param; 526 ITEMS 527 #undef ITEM 528 m_gameList.push_back( pItem ); 529 } 530 } 531 532 GameListQuery::~GameListQuery() 533 { 534 util::clearList( m_gameList ); 535 } 536 537 const std::string& GameListQuery::filterString() const 538 { 539 static const std::string filter = "/iq/query[@xmlns='" + XMLNS_GAMELIST + "']"; 540 return filter; 541 } 542 543 Tag* GameListQuery::tag() const 544 { 545 Tag* t = new Tag( "query" ); 546 t->setXmlns( XMLNS_GAMELIST ); 547 /* 548 RosterData::const_iterator it = m_roster.begin(); 549 for( ; it != m_roster.end(); ++it ) 550 t->addChild( (*it)->tag() ); 551 */ 552 553 // register / unregister command 554 if(!m_command.empty()) 555 t->addChild(new Tag("command", m_command)); 556 557 std::list<GameItemData*>::const_iterator it = m_gameList.begin(); 558 for( ; it != m_gameList.end(); ++it ) 559 t->addChild( (*it)->tag() ); 560 561 return t; 562 } 563 564 StanzaExtension* GameListQuery::clone() const 565 { 566 GameListQuery* q = new GameListQuery(); 567 568 return q; 569 } 570 571 const std::list<GameItemData*>& GameListQuery::gameList() const 572 { 573 return m_gameList; 574 } -
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 gloox::Tag* tag() const 28 { 29 gloox::Tag* i = new gloox::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 //Game - script 29 class ScriptInterface; 30 class GameItemData; 31 32 class XmppClient : public gloox::ConnectionListener, public gloox::MUCRoomHandler, public gloox::IqHandler, public gloox::LogHandler, public gloox::RegistrationHandler, public gloox::MessageHandler 33 { 34 private: 35 //Game - script 36 ScriptInterface& m_ScriptInterface; 37 //Components 38 gloox::Client* _client; 39 gloox::MUCRoom* _mucRoom; 40 gloox::Registration* _registration; 41 //Account infos 42 std::string _username; 43 std::string _password; 44 std::string _nick; 45 std::string _xpartamuppId; 46 47 public: 48 //Basic 49 XmppClient(ScriptInterface& scriptInterface, std::string sUsername, std::string sPassword, std::string sRoom, std::string sNick, bool regOpt = false); 50 virtual ~XmppClient(); 51 52 //Network 53 void connect(); 54 void disconnect(); 55 void recv(); 56 void SendIqGetGameList(); 57 void SendIqRegisterGame(CScriptVal data); 58 void SendIqUnregisterGame(std::string name); 59 60 CScriptValRooted GUIGetPlayerList(); 61 CScriptValRooted GUIGetGameList(); 62 63 //Script 64 ScriptInterface& GetScriptInterface(); 65 66 protected: 67 /* Xmpp handlers */ 68 /* MUC handlers */ 69 virtual void handleMUCParticipantPresence(gloox::MUCRoom*, gloox::MUCRoomParticipant, const gloox::Presence&); 70 virtual bool handleMUCRoomCreation(gloox::MUCRoom*) {return false;} 71 virtual void handleMUCSubject(gloox::MUCRoom*, const std::string&, const std::string&) {} 72 virtual void handleMUCInviteDecline(gloox::MUCRoom*, const gloox::JID&, const std::string&) {} 73 virtual void handleMUCError(gloox::MUCRoom*, gloox::StanzaError); 74 virtual void handleMUCInfo(gloox::MUCRoom*, int, const std::string&, const gloox::DataForm*) {} 75 virtual void handleMUCItems(gloox::MUCRoom*, const std::list<gloox::Disco::Item*, std::allocator<gloox::Disco::Item*> >&); 76 virtual void handleMUCMessage(gloox::MUCRoom* room, const gloox::Message& msg, bool priv); 77 78 /* Log handler */ 79 virtual void handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message); 80 81 /* ConnectionListener handlers*/ 82 virtual void onConnect(); 83 virtual void onDisconnect(gloox::ConnectionError e); 84 virtual bool onTLSConnect(const gloox::CertInfo& info); 85 86 /* Iq Handlers */ 87 virtual bool handleIq(const gloox::IQ& iq); 88 virtual void handleIqID(const gloox::IQ&, int) {} 89 90 /* Registration Handlers */ 91 virtual void handleRegistrationFields(const gloox::JID& /*from*/, int fields, std::string instructions ); 92 virtual void handleRegistrationResult(const gloox::JID& /*from*/, gloox::RegistrationResult result); 93 virtual void handleAlreadyRegistered(const gloox::JID& /*from*/); 94 virtual void handleDataForm(const gloox::JID& /*from*/, const gloox::DataForm& /*form*/); 95 virtual void handleOOB(const gloox::JID& /*from*/, const gloox::OOB& oob); 96 97 /* Message Handler */ 98 virtual void handleMessage(const gloox::Message& msg, gloox::MessageSession * session); 99 100 /* Messages */ 101 public: 102 CScriptValRooted GuiPollMessage(); 103 void SendMUCMessage(std::string message); 104 protected: 105 void PushGuiMessage(const CScriptValRooted& message); 106 void CreateSimpleMessage(std::string type, std::string text, std::string level = "standard"); 107 108 private: 109 /// Map of players 110 std::map<std::string, std::pair<std::string, int> > m_PlayerMap; 111 /// List of games 112 std::list< GameItemData > m_GameList; 113 /// Queue of messages 114 std::deque<CScriptValRooted> m_GuiMessageQueue; 115 }; 116 117 class GameListQuery : public gloox::StanzaExtension 118 { 119 friend class XmppClient; 120 public: 121 GameListQuery(const gloox::Tag* tag = 0); 122 123 ~GameListQuery(); 124 125 // reimplemented from StanzaExtension 126 virtual const std::string& filterString() const; 127 128 // reimplemented from StanzaExtension 129 virtual StanzaExtension* newInstance(const gloox::Tag* tag) const 130 { 131 return new GameListQuery( tag ); 132 } 133 134 // reimplemented from StanzaExtension 135 virtual gloox::Tag* tag() const; 136 137 // reimplemented from StanzaExtension 138 virtual gloox::StanzaExtension* clone() const; 139 140 const std::list<GameItemData*>& gameList() const; 141 142 private: 143 std::string m_command; 144 std::list<GameItemData*> m_gameList; 145 }; 146 147 extern XmppClient *g_XmppClient; 148 149 #endif // XMPPCLIENT_H -
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; … … 319 342 // Update the player list 320 343 g_PlayerAssignments = message.hosts; 321 344 updatePlayerList(); 345 346 if (isServerOnLobby()) 347 { 348 sendRegisterGameStanza(); 349 } 322 350 break; 323 351 324 352 case "start": 353 if (g_Source == "lobby") Engine.StopXmppClient(); 325 354 Engine.SwitchGuiPage("page_loading.xml", { 326 355 "attribs": g_GameAttributes, 327 356 "isNetworked" : g_IsNetworked, … … 942 971 if (g_IsNetworked) 943 972 { 944 973 Engine.SetNetworkGameAttributes(g_GameAttributes); 974 if (isServerOnLobby() && g_LoadingState >= 2) 975 { 976 sendRegisterGameStanza(); 977 } 945 978 } 946 979 else 947 980 { … … 1259 1292 } 1260 1293 return false; 1261 1294 } 1295 1296 function isServerOnLobby() 1297 { 1298 return (g_IsController && g_Source == "lobby") ? true : false; 1299 } 1300 1301 function sendRegisterGameStanza() 1302 { 1303 var selectedMapSize = getGUIObjectByName("mapSize").selected; 1304 var selectedVictoryCondition = getGUIObjectByName("victoryCondition").selected; 1305 1306 var mapSize = getGUIObjectByName("mapSize").list_data[selectedMapSize]; 1307 var victoryCondition = getGUIObjectByName("victoryCondition").list[selectedVictoryCondition]; 1308 1309 var numberOfPlayers = 0; 1310 for (var guid in g_PlayerAssignments) 1311 { 1312 numberOfPlayers++; 1313 } 1314 print(numberOfPlayers); 1315 1316 var nbp = numberOfPlayers ? numberOfPlayers : 1; 1317 var tnbp = g_GameAttributes.settings.PlayerData.length; 1318 1319 gameData = { 1320 "name":g_ServerName, 1321 "mapName":g_GameAttributes.map, 1322 "mapSize":mapSize, 1323 "victoryCondition":victoryCondition, 1324 "nbp":nbp, 1325 "tnbp":tnbp 1326 }; 1327 Engine.SendRegisterGame(gameData); 1328 } -
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
241 241 joystick.camera.rotate.y = 2 242 242 joystick.camera.zoom.in = 5 243 243 joystick.camera.zoom.out = 4 244 245 ; Multiplayer lobby preferences 246 lobby.server = "localhost" 247 lobby.xpartamupp = "xpartamupp"