Ticket #1504: 0ad-multiplayer-lobby-v15-07-2012.diff
File 0ad-multiplayer-lobby-v15-07-2012.diff, 98.1 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
491 491 492 492 493 493 source_dirs = { 494 "lobby", 495 } 496 extern_libs = { 497 "spidermonkey", 498 "gloox", 499 "boost", 500 } 501 setup_static_lib_project("lobby", source_dirs, extern_libs, {}) 502 503 504 source_dirs = { 494 505 "simulation2", 495 506 "simulation2/components", 496 507 "simulation2/helpers", … … 538 549 "boost", 539 550 "enet", 540 551 "libcurl", 552 "gloox", 541 553 } 542 554 setup_static_lib_project("engine", source_dirs, extern_libs, {}) 543 555 … … 580 592 "spidermonkey", 581 593 "sdl", -- key definitions 582 594 "opengl", 583 "boost" 595 "boost", 596 "gloox", 584 597 } 585 598 setup_static_lib_project("gui", source_dirs, extern_libs, {}) 586 599 … … 710 723 "libcurl", 711 724 712 725 "valgrind", 726 727 "gloox", 713 728 } 714 729 715 730 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(); -
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 56 std::vector<ObjectDef> m_ObjectsDefs; 57 58 private: 59 float m_HeadingHeight; 60 61 }; 62 63 #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 "precompiled.h" 2 #include "COList.h" 3 4 #include "ps/CLogger.h" 5 6 COList::COList() : CList(),m_HeadingHeight(30.f) 7 { 8 AddSetting(GUIST_CGUISpriteInstance, "sprite_heading"); 9 } 10 11 void COList::SetupText() 12 { 13 if (!GetGUI()) 14 return; 15 16 CGUIList *pList; 17 GUI<CGUIList>::GetSettingPointer(this, "list_ip", pList); 18 19 //ENSURE(m_GeneratedTexts.size()>=1); 20 21 m_ItemsYPositions.resize( pList->m_Items.size()+1 ); 22 23 // Delete all generated texts. Some could probably be saved, 24 // but this is easier, and this function will never be called 25 // continuously, or even often, so it'll probably be okay. 26 std::vector<SGUIText*>::iterator it; 27 for (it=m_GeneratedTexts.begin(); it!=m_GeneratedTexts.end(); ++it) 28 { 29 if (*it) 30 delete *it; 31 } 32 m_GeneratedTexts.clear(); 33 34 CStrW font; 35 if (GUI<CStrW>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) 36 // Use the default if none is specified 37 // TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style. 38 font = L"default"; 39 40 //CGUIString caption; 41 bool scrollbar; 42 //GUI<CGUIString>::GetSetting(this, "caption", caption); 43 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 44 45 float width = GetListRect().GetWidth(); 46 // remove scrollbar if applicable 47 if (scrollbar && GetScrollBar(0).GetStyle()) 48 width -= GetScrollBar(0).GetStyle()->m_Width; 49 50 float buffer_zone=0.f; 51 GUI<float>::GetSetting(this, "buffer_zone", buffer_zone); 52 53 54 for (unsigned int c=0; c<m_ObjectsDefs.size(); ++c) 55 { 56 SGUIText *text = new SGUIText(); 57 CGUIString gui_string; 58 gui_string.SetValue(m_ObjectsDefs[c].m_Heading); 59 *text = GetGUI()->GenerateText(gui_string, font, width, buffer_zone, this); 60 AddText(text); 61 } 62 63 64 // Generate texts 65 float buffered_y = 0.f; 66 67 for (int i=0; i<(int)pList->m_Items.size(); ++i) 68 { 69 m_ItemsYPositions[i] = buffered_y; 70 for (unsigned int c=0; c<m_ObjectsDefs.size(); ++c) 71 { 72 CGUIList * pList_c; 73 GUI<CGUIList>::GetSettingPointer(this, m_ObjectsDefs[c].m_Id, pList_c); 74 SGUIText *text = new SGUIText(); 75 *text = GetGUI()->GenerateText(pList_c->m_Items[i], font, width, buffer_zone, this); 76 if (c==0) 77 buffered_y += text->m_Size.cy; 78 AddText(text); 79 } 80 } 81 82 m_ItemsYPositions[pList->m_Items.size()] = buffered_y; 83 84 //if (! scrollbar) 85 // CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]); 86 87 // Setup scrollbar 88 if (scrollbar) 89 { 90 GetScrollBar(0).SetScrollRange( m_ItemsYPositions.back() ); 91 GetScrollBar(0).SetScrollSpace( GetListRect().GetHeight() ); 92 93 CRect rect = GetListRect(); 94 GetScrollBar(0).SetX( rect.right ); 95 GetScrollBar(0).SetY( rect.top ); 96 GetScrollBar(0).SetZ( GetBufferedZ() ); 97 GetScrollBar(0).SetLength( rect.bottom - rect.top ); 98 } 99 } 100 101 CRect COList::GetListRect() const 102 { 103 return m_CachedActualSize + CRect(0, m_HeadingHeight, 0, 0); 104 } 105 106 void COList::HandleMessage(SGUIMessage &Message) 107 { 108 CList::HandleMessage(Message); 109 // switch (Message.type) 110 // { 111 // case GUIM_SETTINGS_UPDATED: 112 // if (Message.value.Find("list_") != -1) 113 // { 114 // SetupText(); 115 // } 116 // } 117 } 118 119 bool COList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile) 120 { 121 int elmt_item = pFile->GetElementID("item"); 122 int elmt_heading = pFile->GetElementID("heading"); 123 int elmt_def = pFile->GetElementID("def"); 124 125 if (child.GetNodeName() == elmt_item) 126 { 127 AddItem(child.GetText().FromUTF8(), child.GetText().FromUTF8()); 128 return true; 129 } 130 else if (child.GetNodeName() == elmt_heading) 131 { 132 CStrW text (child.GetText().FromUTF8()); 133 134 return true; 135 } 136 else if (child.GetNodeName() == elmt_def) 137 { 138 ObjectDef oDef; 139 140 XMBAttributeList attributes = child.GetAttributes(); 141 for (int i=0; i<attributes.Count; ++i) 142 { 143 XMBAttribute attr = attributes.Item(i); 144 CStr attr_name (pFile->GetAttributeString(attr.Name)); 145 CStr attr_value (attr.Value); 146 147 if (attr_name == "color") 148 { 149 CColor color; 150 if (!GUI<CColor>::ParseString(attr_value.FromUTF8(), color)) 151 LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); 152 else oDef.m_TextColor = color; 153 } 154 else if (attr_name == "id") 155 { 156 oDef.m_Id = "list_"+attr_value; 157 } 158 else if (attr_name == "width") 159 { 160 int width; 161 if (!GUI<int>::ParseString(attr_value.FromUTF8(), width)) 162 LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); 163 else 164 oDef.m_Width = width; 165 } 166 else if (attr_name == "heading") 167 { 168 oDef.m_Heading = attr_value.FromUTF8(); 169 } 170 171 } 172 173 m_ObjectsDefs.push_back(oDef); 174 175 AddSetting(GUIST_CGUIList, oDef.m_Id); 176 SetupText(); 177 178 return true; 179 } 180 else 181 { 182 return false; 183 } 184 } 185 186 void COList::DrawList(const int &selected, 187 const CStr& _sprite, 188 const CStr& _sprite_selected, 189 const CStr& _textcolor) 190 { 191 float bz = GetBufferedZ(); 192 193 // First call draw on ScrollBarOwner 194 bool scrollbar; 195 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 196 197 if (scrollbar) 198 { 199 // Draw scrollbar 200 IGUIScrollBarOwner::Draw(); 201 } 202 203 if (GetGUI()) 204 { 205 CRect rect = GetListRect(); 206 207 CGUISpriteInstance *sprite=NULL, *sprite_selectarea=NULL; 208 int cell_id; 209 GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite, sprite); 210 GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite_selected, sprite_selectarea); 211 GUI<int>::GetSetting(this, "cell_id", cell_id); 212 213 CGUIList *pList; 214 GUI<CGUIList>::GetSettingPointer(this, "list_name", pList); 215 216 GetGUI()->DrawSprite(*sprite, cell_id, bz, rect); 217 218 float scroll=0.f; 219 if (scrollbar) 220 { 221 scroll = GetScrollBar(0).GetPos(); 222 } 223 224 if (selected != -1) 225 { 226 ENSURE(selected >= 0 && selected+1 < (int)m_ItemsYPositions.size()); 227 228 // Get rectangle of selection: 229 CRect rect_sel(rect.left, rect.top + m_ItemsYPositions[selected] - scroll, 230 rect.right, rect.top + m_ItemsYPositions[selected+1] - scroll); 231 232 if (rect_sel.top <= rect.bottom && 233 rect_sel.bottom >= rect.top) 234 { 235 if (rect_sel.bottom > rect.bottom) 236 rect_sel.bottom = rect.bottom; 237 if (rect_sel.top < rect.top) 238 rect_sel.top = rect.top; 239 240 if (scrollbar) 241 { 242 // Remove any overlapping area of the scrollbar. 243 if (rect_sel.right > GetScrollBar(0).GetOuterRect().left && 244 rect_sel.right <= GetScrollBar(0).GetOuterRect().right) 245 rect_sel.right = GetScrollBar(0).GetOuterRect().left; 246 247 if (rect_sel.left >= GetScrollBar(0).GetOuterRect().left && 248 rect_sel.left < GetScrollBar(0).GetOuterRect().right) 249 rect_sel.left = GetScrollBar(0).GetOuterRect().right; 250 } 251 252 GetGUI()->DrawSprite(*sprite_selectarea, cell_id, bz+0.05f, rect_sel); 253 } 254 } 255 256 CColor color; 257 GUI<CColor>::GetSetting(this, _textcolor, color); 258 259 CGUISpriteInstance *sprite_heading=NULL; 260 GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite_heading", sprite_heading); 261 CRect rect_head(m_CachedActualSize.left, m_CachedActualSize.top, m_CachedActualSize.right, 262 m_CachedActualSize.top + m_HeadingHeight); 263 GetGUI()->DrawSprite(*sprite_heading, cell_id, bz, rect_head); 264 265 float xpos = 0; 266 for (unsigned int def=0; def< m_ObjectsDefs.size(); ++def) 267 { 268 DrawText(def, color, m_CachedActualSize.TopLeft() + CPos(xpos, 4), bz+0.1f, rect_head); 269 xpos += m_ObjectsDefs[def].m_Width; 270 } 271 272 for (int i=0; i<(int)pList->m_Items.size(); ++i) 273 { 274 if (m_ItemsYPositions[i+1] - scroll < 0 || 275 m_ItemsYPositions[i] - scroll > rect.GetHeight()) 276 continue; 277 278 // Clipping area (we'll have to substract the scrollbar) 279 CRect cliparea = GetListRect(); 280 281 if (scrollbar) 282 { 283 if (cliparea.right > GetScrollBar(0).GetOuterRect().left && 284 cliparea.right <= GetScrollBar(0).GetOuterRect().right) 285 cliparea.right = GetScrollBar(0).GetOuterRect().left; 286 287 if (cliparea.left >= GetScrollBar(0).GetOuterRect().left && 288 cliparea.left < GetScrollBar(0).GetOuterRect().right) 289 cliparea.left = GetScrollBar(0).GetOuterRect().right; 290 } 291 292 xpos = 0; 293 for (unsigned int def=0; def< m_ObjectsDefs.size(); ++def) 294 { 295 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); 296 xpos += m_ObjectsDefs[def].m_Width; 297 } 298 } 299 } 300 } -
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 5 //debug 6 #include <iostream> 7 8 //Gloox 9 #include <gloox/rostermanager.h> 10 #include <gloox/rosteritem.h> 11 #include <gloox/error.h> 12 13 //Game - script 14 #include "scriptinterface/ScriptInterface.h" 15 16 //Configuration 17 #include "ps/ConfigDB.h" 18 19 using namespace gloox; 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 //Hack 32 #if 1 33 #if OS_WIN 34 const std::string gloox::EmptyString = ""; 35 #endif 36 #endif 37 38 //utils 39 std::string StanzaErrorToString(StanzaError& err) 40 { 41 std::string msg; 42 #define CASE(X, Y) case X: return Y; 43 switch (err) 44 { 45 CASE(StanzaErrorBadRequest, "Bad request") 46 CASE(StanzaErrorConflict, "Player name already used") 47 CASE(StanzaErrorFeatureNotImplemented, "Feature not implemented") 48 CASE(StanzaErrorForbidden, "Forbidden") 49 CASE(StanzaErrorGone, "Recipient or server gone") 50 CASE(StanzaErrorInternalServerError, "Internal server error") 51 CASE(StanzaErrorItemNotFound, "Item not found") 52 CASE(StanzaErrorJidMalformed, "Jid malformed") 53 CASE(StanzaErrorNotAcceptable, "Not acceptable") 54 CASE(StanzaErrorNotAllowed, "Not allowed") 55 CASE(StanzaErrorNotAuthorized, "Not authorized") 56 CASE(StanzaErrorNotModified, "Not modified") 57 CASE(StanzaErrorPaymentRequired, "Payment required") 58 CASE(StanzaErrorRecipientUnavailable, "Recipient unavailable") 59 CASE(StanzaErrorRedirect, "Redirect") 60 CASE(StanzaErrorRegistrationRequired, "Registration required") 61 CASE(StanzaErrorRemoteServerNotFound, "Remote server not found") 62 CASE(StanzaErrorRemoteServerTimeout, "Remote server timeout") 63 CASE(StanzaErrorResourceConstraint, "Resource constraint") 64 CASE(StanzaErrorServiceUnavailable, "Service unavailable") 65 CASE(StanzaErrorSubscribtionRequired, "Subscribtion Required") 66 CASE(StanzaErrorUndefinedCondition, "Undefined condition") 67 CASE(StanzaErrorUnexpectedRequest, "Unexpected request") 68 CASE(StanzaErrorUnknownSender, "Unknown sender") 69 default: 70 return "Error undefined"; 71 } 72 #undef CASE 73 } 74 75 XmppClient::XmppClient(ScriptInterface& scriptInterface, std::string sUsername, std::string sPassword, std::string sRoom, std::string sNick, bool regOpt) 76 : m_ScriptInterface(scriptInterface), _client(NULL), _mucRoom(NULL), _registration(NULL), _username(sUsername), _password(sPassword), _nick(sNick) 77 { 78 // Read lobby configuration from default.cfg 79 std::string sServer; 80 std::string sXpartamupp; 81 CFG_GET_USER_VAL("lobby.server", String, sServer); 82 CFG_GET_USER_VAL("lobby.xpartamupp", String, sXpartamupp); 83 84 _xpartamuppId = sXpartamupp+std::string("@")+sServer+std::string("/CC"); 85 JID clientJid(sUsername+std::string("@")+sServer+std::string("/0ad")); 86 JID roomJid(sRoom+std::string("@conference.")+sServer+std::string("/")+sNick); 87 88 // If we are connecting, use the full jid and a password 89 // If we are registering, only use the server name 90 if(!regOpt) 91 _client = new Client(clientJid, sPassword); 92 else 93 _client = new Client(sServer); 94 95 _client->registerConnectionListener( this ); 96 _client->setPresence(Presence::Available, -1); 97 _client->disco()->setVersion( "TestProg", "1.0" ); 98 _client->disco()->setIdentity( "client", "bot" ); 99 _client->setCompression(false); 100 101 _client->registerStanzaExtension( new GameListQuery() ); 102 _client->registerIqHandler( this, ExtGameListQuery); 103 104 _client->registerMessageHandler( this ); 105 106 StringList ca; 107 ca.push_back( "/path/to/cacert.crt" ); 108 _client->setCACerts( ca ); 109 110 // Uncomment to see the raw stanzas 111 //_client->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this ); 112 113 if (!regOpt) 114 { 115 // Create a Multi User Chat Room 116 _mucRoom = new MUCRoom(_client, roomJid, this, 0); 117 // Disable the history because its anoying 118 _mucRoom->setRequestHistory(0, MUCRoom::HistoryMaxStanzas); 119 } 120 else 121 { 122 // Registration 123 _registration = new Registration( _client ); 124 _registration->registerRegistrationHandler( this ); 125 } 126 } 127 128 XmppClient::~XmppClient() 129 { 130 DbgXMPP("XmppClient destroyed"); 131 delete _registration; 132 delete _mucRoom; 133 delete _client; 134 } 135 136 // Game - script 137 ScriptInterface& XmppClient::GetScriptInterface() 138 { 139 return m_ScriptInterface; 140 } 141 142 //Network 143 void XmppClient::connect() 144 { 145 _client->connect(false); 146 } 147 148 void XmppClient::disconnect() 149 { 150 _client->disconnect(); 151 } 152 153 void XmppClient::recv() 154 { 155 _client->recv(1); 156 } 157 158 /* 159 * MUC Handlers 160 */ 161 void XmppClient::handleMUCParticipantPresence(gloox::MUCRoom*, gloox::MUCRoomParticipant participant, const gloox::Presence& presence) 162 { 163 //std::string jid = participant.jid->full(); 164 std::string nick = participant.nick->resource(); 165 gloox::Presence::PresenceType presenceType = presence.presence(); 166 if (presenceType == Presence::Unavailable) 167 { 168 DbgXMPP(nick << " left the room"); 169 m_PlayerMap.erase(nick); 170 } 171 else 172 { 173 DbgXMPP(nick << " is in the room"); 174 m_PlayerMap[nick] = std::pair<std::string, int>(nick, (int)presenceType); 175 } 176 CreateSimpleMessage("system", "playerlist updated", "internal"); 177 } 178 179 void XmppClient::handleMUCMessage( MUCRoom*, const Message& msg, bool ) 180 { 181 DbgXMPP(msg.from().resource() << " said " << msg.body()); 182 std::string nick = msg.from().resource(); 183 std::string body = msg.body(); 184 185 CScriptValRooted message; 186 GetScriptInterface().Eval("({ 'type':'mucmessage'})", message); 187 GetScriptInterface().SetProperty(message.get(), "from", nick); 188 GetScriptInterface().SetProperty(message.get(), "text", body); 189 PushGuiMessage(message); 190 } 191 192 void XmppClient::handleMUCError(gloox::MUCRoom*, gloox::StanzaError err) 193 { 194 std::string msg = StanzaErrorToString(err); 195 CreateSimpleMessage("system", msg, "error"); 196 } 197 198 void XmppClient::handleMUCItems( MUCRoom * /*room*/, const Disco::ItemList& items ) 199 { 200 m_PlayerMap.clear(); 201 202 // Add the received items 203 Disco::ItemList::const_iterator it = items.begin(); 204 for( ; it != items.end(); ++it ) 205 { 206 std::string jid = (*it)->jid().full().c_str(); 207 std::string nick = (*it)->name().c_str(); 208 m_PlayerMap[nick] = std::pair<std::string, int>(nick, Presence::Available); 209 //printf( "%s -- %s is an item here\n", (*it)->jid().full().c_str(), (*it)->name().c_str() ); 210 } 211 CreateSimpleMessage("system", "playerlist updated", "internal"); 212 } 213 214 /* 215 * Log (debug) Handler 216 */ 217 void XmppClient::handleLog( LogLevel level, LogArea area, const std::string& message ) 218 { 219 std::cout << "log: level: " << level << ", area: " << area << ", message: " << message << std::endl; 220 } 221 222 /* 223 * IQ Handler 224 */ 225 bool XmppClient::handleIq( const IQ& iq ) 226 { 227 DbgXMPP("handleIq [" << iq.tag()->xml() << "]"); 228 229 if(iq.subtype() == gloox::IQ::Result) 230 { 231 const GameListQuery* q = iq.findExtension<GameListQuery>( ExtGameListQuery ); 232 if(q) 233 { 234 m_GameList.clear(); 235 std::list<GameItemData*>::const_iterator it = q->gameList().begin(); 236 for(; it != q->gameList().end(); ++it) 237 { 238 m_GameList.push_back(**it); 239 } 240 CreateSimpleMessage("system", "gamelist updated", "internal"); 241 } 242 } 243 else if(iq.subtype() == gloox::IQ::Error) 244 { 245 StanzaError err = iq.error()->error(); 246 std::string msg = StanzaErrorToString(err); 247 CreateSimpleMessage("system", msg, "error"); 248 } 249 else 250 { 251 CreateSimpleMessage("system", std::string("unknown subtype : ") + iq.tag()->name(), "error"); 252 } 253 254 return true; 255 } 256 257 /* 258 * Connection Handlers 259 */ 260 void XmppClient::onConnect() 261 { 262 if (_mucRoom) 263 { 264 CreateSimpleMessage("system", "connected"); 265 _mucRoom->join(); 266 //_mucRoom->getRoomInfo(); 267 _mucRoom->getRoomItems(); 268 SendIqGetGameList(); 269 } 270 271 if (_registration) 272 { 273 _registration->fetchRegistrationFields(); 274 } 275 } 276 277 void XmppClient::onDisconnect( ConnectionError e ) 278 { 279 // Make sure we properly leave the room so than 280 // everything work if we decide to come back later 281 if (_mucRoom) 282 _mucRoom->leave(); 283 284 if( e == ConnAuthenticationFailed ) 285 CreateSimpleMessage("system", "authentication failed", "error"); 286 else 287 CreateSimpleMessage("system", "disconnected"); 288 289 m_PlayerMap.clear(); 290 m_GameList.clear(); 291 } 292 293 bool XmppClient::onTLSConnect( const CertInfo& ) 294 { 295 return true; 296 } 297 298 /* 299 * Requests 300 */ 301 302 /* Request GameList from cloud */ 303 void XmppClient::SendIqGetGameList() 304 { 305 JID xpartamuppJid(_xpartamuppId); 306 307 // Send IQ 308 IQ iq(gloox::IQ::Get, xpartamuppJid); 309 iq.addExtension( new GameListQuery() ); 310 DbgXMPP("SendIqGetGameList [" << iq.tag()->xml() << "]"); 311 _client->send(iq); 312 } 313 314 /* Register a game */ 315 void XmppClient::SendIqRegisterGame(CScriptVal data) 316 { 317 JID xpartamuppJid(_xpartamuppId); 318 319 std::string name, mapName, mapSize, victoryCondition, nbp, tnbp; 320 GetScriptInterface().GetProperty(data.get(), "name", name); 321 GetScriptInterface().GetProperty(data.get(), "mapName", mapName); 322 GetScriptInterface().GetProperty(data.get(), "mapSize", mapSize); 323 GetScriptInterface().GetProperty(data.get(), "victoryCondition", victoryCondition); 324 GetScriptInterface().GetProperty(data.get(), "nbp", nbp); 325 GetScriptInterface().GetProperty(data.get(), "tnbp", tnbp); 326 327 // Send IQ 328 GameListQuery* g = new GameListQuery(); 329 g->m_command = "register"; 330 /* This "x" fake ip will be overwritten by the ip stamp XMPP module */ 331 GameItemData *pItemData = new GameItemData(name, "x"); 332 pItemData->m_mapName = mapName; 333 pItemData->m_mapSize = mapSize; 334 pItemData->m_victoryCondition = victoryCondition; 335 pItemData->m_nbp = nbp; 336 pItemData->m_tnbp = tnbp; 337 g->m_gameList.push_back( pItemData ); 338 339 IQ iq(gloox::IQ::Set, xpartamuppJid); 340 iq.addExtension( g ); 341 DbgXMPP("SendIqRegisterGame [" << iq.tag()->xml() << "]"); 342 _client->send(iq); 343 } 344 345 /* Unregister a game */ 346 void XmppClient::SendIqUnregisterGame(std::string name) 347 { 348 JID xpartamuppJid(_xpartamuppId); 349 350 // Send IQ 351 GameListQuery* g = new GameListQuery(); 352 g->m_command = "unregister"; 353 g->m_gameList.push_back( new GameItemData(name) ); 354 355 IQ iq(gloox::IQ::Set, xpartamuppJid); 356 iq.addExtension( g ); 357 DbgXMPP("SendIqUnregisterGame [" << iq.tag()->xml() << "]"); 358 _client->send(iq); 359 } 360 361 /* 362 * Registration 363 */ 364 void XmppClient::handleRegistrationFields( const JID& /*from*/, int fields, std::string ) 365 { 366 RegistrationFields vals; 367 vals.username = _username; 368 vals.password = _password; 369 _registration->createAccount( fields, vals ); 370 } 371 372 void XmppClient::handleRegistrationResult( const JID& /*from*/, RegistrationResult result ) 373 { 374 if (result == gloox::RegistrationSuccess) 375 { 376 CreateSimpleMessage("system", "registered"); 377 } 378 else 379 { 380 std::string msg; 381 #define CASE(X, Y) case X: msg = Y; break; 382 switch(result) 383 { 384 CASE(RegistrationNotAcceptable, "Registration not acceptable") 385 CASE(RegistrationConflict, "Registration conflict") 386 CASE(RegistrationNotAuthorized, "Registration not authorized") 387 CASE(RegistrationBadRequest, "Registration bad request") 388 CASE(RegistrationForbidden, "Registration forbidden") 389 CASE(RegistrationRequired, "Registration required") 390 CASE(RegistrationUnexpectedRequest, "Registration unexpected request") 391 CASE(RegistrationNotAllowed, "Registration not allowed") 392 default: msg = "Registration unknown error"; 393 } 394 #undef CASE 395 CreateSimpleMessage("system", msg, "error"); 396 } 397 disconnect(); 398 } 399 400 void XmppClient::handleAlreadyRegistered( const JID& /*from*/ ) 401 { 402 DbgXMPP("the account already exists"); 403 } 404 405 void XmppClient::handleDataForm( const JID& /*from*/, const DataForm& /*form*/ ) 406 { 407 DbgXMPP("dataForm received"); 408 } 409 410 void XmppClient::handleOOB( const JID& /*from*/, const OOB& /* oob */ ) 411 { 412 DbgXMPP("OOB registration requested"); 413 } 414 415 /** 416 * Message 417 */ 418 void XmppClient::handleMessage( const Message& msg, MessageSession * /*session*/ ) 419 { 420 DbgXMPP("type " << msg.subtype() << ", subject " << msg.subject().c_str() 421 << ", message " << msg.body().c_str() << ", thread id " << msg.thread().c_str()); 422 423 std::string nick = msg.from().resource(); 424 std::string body = msg.body(); 425 426 CScriptValRooted message; 427 GetScriptInterface().Eval("({ 'type':'message'})", message); 428 GetScriptInterface().SetProperty(message.get(), "from", nick); 429 GetScriptInterface().SetProperty(message.get(), "text", body); 430 PushGuiMessage(message); 431 } 432 433 434 435 /* Requests from GUI */ 436 CScriptValRooted XmppClient::GUIGetPlayerList() 437 { 438 CScriptValRooted playerList; 439 GetScriptInterface().Eval("({})", playerList); 440 for(std::map<std::string, std::pair<std::string, int> >::iterator it = m_PlayerMap.begin(); it != m_PlayerMap.end(); ++it) 441 { 442 CScriptValRooted player; 443 GetScriptInterface().Eval("({})", player); 444 GetScriptInterface().SetProperty(player.get(), "name", it->second.first.c_str()); 445 GetScriptInterface().SetProperty(player.get(), "presenceType", it->second.first); 446 447 GetScriptInterface().SetProperty(playerList.get(), it->second.first.c_str(), player); 448 } 449 450 return playerList; 451 } 452 453 CScriptValRooted XmppClient::GUIGetGameList() 454 { 455 CScriptValRooted gameList; 456 GetScriptInterface().Eval("([])", gameList); 457 for(std::list<GameItemData>::iterator it = m_GameList.begin(); it !=m_GameList.end(); ++it) 458 { 459 CScriptValRooted game; 460 GetScriptInterface().Eval("({})", game); 461 462 #define ITEM(param)\ 463 GetScriptInterface().SetProperty(game.get(), #param, it->m_##param .c_str()); 464 ITEMS 465 #undef ITEM 466 467 GetScriptInterface().CallFunctionVoid(gameList.get(), "push", game); 468 } 469 470 return gameList; 471 } 472 473 /* Messages */ 474 CScriptValRooted XmppClient::GuiPollMessage() 475 { 476 if (m_GuiMessageQueue.empty()) 477 return CScriptValRooted(); 478 479 CScriptValRooted r = m_GuiMessageQueue.front(); 480 m_GuiMessageQueue.pop_front(); 481 return r; 482 } 483 484 void XmppClient::SendMUCMessage(std::string message) 485 { 486 _mucRoom->send(message); 487 } 488 489 void XmppClient::PushGuiMessage(const CScriptValRooted& message) 490 { 491 ENSURE(!message.undefined()); 492 493 m_GuiMessageQueue.push_back(message); 494 } 495 496 void XmppClient::CreateSimpleMessage(std::string type, std::string text, std::string level) 497 { 498 CScriptValRooted message; 499 GetScriptInterface().Eval("({})", message); 500 GetScriptInterface().SetProperty(message.get(), "type", type); 501 GetScriptInterface().SetProperty(message.get(), "level", level); 502 GetScriptInterface().SetProperty(message.get(), "text", text); 503 PushGuiMessage(message); 504 } 505 506 /* 507 * GameListQuery, custom IQ Stanza 508 */ 509 510 GameListQuery::GameListQuery( const Tag* tag ) 511 : StanzaExtension( ExtGameListQuery ) 512 { 513 if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_GAMELIST ) 514 return; 515 516 const Tag* c = tag->findTag( "query/game" ); 517 if (c) 518 m_command = c->cdata(); 519 520 const ConstTagList& l = tag->findTagList( "query/game" ); 521 ConstTagList::const_iterator it = l.begin(); 522 for( ; it != l.end(); ++it ) 523 { 524 GameItemData *pItem = new GameItemData(); 525 #define ITEM(param)\ 526 const std::string param = (*it)->findAttribute( #param ); \ 527 pItem->m_##param = param; 528 ITEMS 529 #undef ITEM 530 m_gameList.push_back( pItem ); 531 } 532 } 533 534 GameListQuery::~GameListQuery() 535 { 536 util::clearList( m_gameList ); 537 } 538 539 const std::string& GameListQuery::filterString() const 540 { 541 static const std::string filter = "/iq/query[@xmlns='" + XMLNS_GAMELIST + "']"; 542 return filter; 543 } 544 545 Tag* GameListQuery::tag() const 546 { 547 Tag* t = new Tag( "query" ); 548 t->setXmlns( XMLNS_GAMELIST ); 549 /* 550 RosterData::const_iterator it = m_roster.begin(); 551 for( ; it != m_roster.end(); ++it ) 552 t->addChild( (*it)->tag() ); 553 */ 554 555 // register / unregister command 556 if(!m_command.empty()) 557 t->addChild(new Tag("command", m_command)); 558 559 std::list<GameItemData*>::const_iterator it = m_gameList.begin(); 560 for( ; it != m_gameList.end(); ++it ) 561 t->addChild( (*it)->tag() ); 562 563 return t; 564 } 565 566 StanzaExtension* GameListQuery::clone() const 567 { 568 GameListQuery* q = new GameListQuery(); 569 570 return q; 571 } 572 573 const std::list<GameItemData*>& GameListQuery::gameList() const 574 { 575 return m_gameList; 576 } -
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 #if OS_WIN 5 // Prevent gloox from pulling in windows.h (which causes conflicts) 6 // and defines what is necessary in order to compile the lobby 7 #define _WINDOWS_ 8 9 //Taken from WinDef.h 10 #define CONST const 11 typedef unsigned char UCHAR; 12 typedef UCHAR *PUCHAR; 13 typedef unsigned long ULONG; 14 typedef ULONG *PULONG; 15 #define OPTIONAL 16 17 // Taken from WinNT.h 18 #define VOID void 19 typedef char CHAR; 20 typedef long LONG; 21 typedef wchar_t WCHAR; 22 typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR; 23 typedef __nullterminated CHAR *NPSTR, *LPSTR, *PSTR; 24 typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR; 25 typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR; 26 typedef unsigned char BYTE; 27 typedef BYTE BOOLEAN; 28 typedef BOOLEAN *PBOOLEAN; 29 typedef void *PVOID; 30 31 //Taken from BaseTsd.h 32 #if defined(_WIN64) 33 typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; 34 #else 35 typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR; 36 #endif 37 #include "specstrings.h" 38 39 #endif 40 41 //network 42 #include <gloox/jid.h> 43 #include <gloox/client.h> 44 #include <gloox/mucroom.h> 45 #include <gloox/message.h> 46 47 #include <gloox/messagehandler.h> 48 #include <gloox/presencehandler.h> 49 #include <gloox/mucroomhandler.h> 50 #include <gloox/loghandler.h> 51 #include <gloox/connectionlistener.h> 52 #include <gloox/registration.h> 53 54 #include <gloox/iq.h> 55 #include <gloox/iqhandler.h> 56 57 //game - script 58 #include <deque> 59 #include "scriptinterface/ScriptVal.h" 60 61 //Global Gamelist Extension 62 #define ExtGameListQuery 1403 63 const std::string XMLNS_GAMELIST = "jabber:iq:gamelist"; 64 65 //Game - script 66 class ScriptInterface; 67 class GameItemData; 68 69 class XmppClient : public gloox::ConnectionListener, public gloox::MUCRoomHandler, public gloox::IqHandler, public gloox::LogHandler, public gloox::RegistrationHandler, public gloox::MessageHandler 70 { 71 private: 72 //Game - script 73 ScriptInterface& m_ScriptInterface; 74 //Components 75 gloox::Client* _client; 76 gloox::MUCRoom* _mucRoom; 77 gloox::Registration* _registration; 78 //Account infos 79 std::string _username; 80 std::string _password; 81 std::string _nick; 82 std::string _xpartamuppId; 83 84 public: 85 //Basic 86 XmppClient(ScriptInterface& scriptInterface, std::string sUsername, std::string sPassword, std::string sRoom, std::string sNick, bool regOpt = false); 87 virtual ~XmppClient(); 88 89 //Network 90 void connect(); 91 void disconnect(); 92 void recv(); 93 void SendIqGetGameList(); 94 void SendIqRegisterGame(CScriptVal data); 95 void SendIqUnregisterGame(std::string name); 96 97 CScriptValRooted GUIGetPlayerList(); 98 CScriptValRooted GUIGetGameList(); 99 100 //Script 101 ScriptInterface& GetScriptInterface(); 102 103 protected: 104 /* Xmpp handlers */ 105 /* MUC handlers */ 106 virtual void handleMUCParticipantPresence(gloox::MUCRoom*, gloox::MUCRoomParticipant, const gloox::Presence&); 107 virtual bool handleMUCRoomCreation(gloox::MUCRoom*) {return false;} 108 virtual void handleMUCSubject(gloox::MUCRoom*, const std::string&, const std::string&) {} 109 virtual void handleMUCInviteDecline(gloox::MUCRoom*, const gloox::JID&, const std::string&) {} 110 virtual void handleMUCError(gloox::MUCRoom*, gloox::StanzaError); 111 virtual void handleMUCInfo(gloox::MUCRoom*, int, const std::string&, const gloox::DataForm*) {} 112 virtual void handleMUCItems(gloox::MUCRoom*, const std::list<gloox::Disco::Item*, std::allocator<gloox::Disco::Item*> >&); 113 virtual void handleMUCMessage(gloox::MUCRoom* room, const gloox::Message& msg, bool priv); 114 115 /* Log handler */ 116 virtual void handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message); 117 118 /* ConnectionListener handlers*/ 119 virtual void onConnect(); 120 virtual void onDisconnect(gloox::ConnectionError e); 121 virtual bool onTLSConnect(const gloox::CertInfo& info); 122 123 /* Iq Handlers */ 124 virtual bool handleIq(const gloox::IQ& iq); 125 virtual void handleIqID(const gloox::IQ&, int) {} 126 127 /* Registration Handlers */ 128 virtual void handleRegistrationFields(const gloox::JID& /*from*/, int fields, std::string instructions ); 129 virtual void handleRegistrationResult(const gloox::JID& /*from*/, gloox::RegistrationResult result); 130 virtual void handleAlreadyRegistered(const gloox::JID& /*from*/); 131 virtual void handleDataForm(const gloox::JID& /*from*/, const gloox::DataForm& /*form*/); 132 virtual void handleOOB(const gloox::JID& /*from*/, const gloox::OOB& oob); 133 134 /* Message Handler */ 135 virtual void handleMessage(const gloox::Message& msg, gloox::MessageSession * session); 136 137 /* Messages */ 138 public: 139 CScriptValRooted GuiPollMessage(); 140 void SendMUCMessage(std::string message); 141 protected: 142 void PushGuiMessage(const CScriptValRooted& message); 143 void CreateSimpleMessage(std::string type, std::string text, std::string level = "standard"); 144 145 private: 146 /// Map of players 147 std::map<std::string, std::pair<std::string, int> > m_PlayerMap; 148 /// List of games 149 std::list< GameItemData > m_GameList; 150 /// Queue of messages 151 std::deque<CScriptValRooted> m_GuiMessageQueue; 152 }; 153 154 class GameListQuery : public gloox::StanzaExtension 155 { 156 friend class XmppClient; 157 public: 158 GameListQuery(const gloox::Tag* tag = 0); 159 160 ~GameListQuery(); 161 162 // reimplemented from StanzaExtension 163 virtual const std::string& filterString() const; 164 165 // reimplemented from StanzaExtension 166 virtual StanzaExtension* newInstance(const gloox::Tag* tag) const 167 { 168 return new GameListQuery( tag ); 169 } 170 171 // reimplemented from StanzaExtension 172 virtual gloox::Tag* tag() const; 173 174 // reimplemented from StanzaExtension 175 virtual gloox::StanzaExtension* clone() const; 176 177 const std::list<GameItemData*>& gameList() const; 178 179 private: 180 std::string m_command; 181 std::list<GameItemData*> m_gameList; 182 }; 183 184 extern XmppClient *g_XmppClient; 185 186 #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; … … 79 85 default: 80 86 error("Unexpected 'type' in gamesetup init: "+attribs.type); 81 87 } 88 89 switch (attribs.source) 90 { 91 case "mainmenu": 92 g_Source = "mainmenu"; 93 break; 94 case "lobby": 95 g_Source = "lobby"; 96 break; 97 default: 98 error("Unrecognised source : " + attribs.source); 99 } 100 101 if (attribs.serverName) 102 g_ServerName = attribs.serverName; 103 104 // Init the Cancel Button caption and tooltip 105 var cancelButton = getGUIObjectByName("cancelGame"); 106 if(g_Source != "lobby") 107 { 108 cancelButton.caption = "Main menu"; 109 cancelButton.tooltip = "Return to the main menu." 110 } 111 else 112 { 113 cancelButton.caption = "Quit"; 114 cancelButton.tooltip = "Return to the lobby." 115 } 116 82 117 } 83 118 84 119 // Called after the map data is loaded and cached … … 168 203 updateGameAttributes(); 169 204 } 170 205 }; 206 mapSize.selected = 0; 171 207 172 208 getGUIObjectByName("revealMap").onPress = function() 173 209 { // Update attributes so other players can see change … … 295 331 { 296 332 case "disconnected": 297 333 Engine.DisconnectNetworkGame(); 334 if (isServerOnLobby()) Engine.SendUnregisterGame(g_ServerName); 298 335 Engine.PopGuiPage(); 299 336 reportDisconnect(message.reason); 300 337 break; … … 333 370 // Update the player list 334 371 g_PlayerAssignments = message.hosts; 335 372 updatePlayerList(); 373 374 if (isServerOnLobby()) 375 { 376 sendRegisterGameStanza(); 377 } 336 378 break; 337 379 338 380 case "start": 381 if (g_Source == "lobby") Engine.StopXmppClient(); 339 382 Engine.SwitchGuiPage("page_loading.xml", { 340 383 "attribs": g_GameAttributes, 341 384 "isNetworked" : g_IsNetworked, … … 984 1027 if (g_IsNetworked) 985 1028 { 986 1029 Engine.SetNetworkGameAttributes(g_GameAttributes); 1030 if (isServerOnLobby() && g_LoadingState >= 2) 1031 { 1032 sendRegisterGameStanza(); 1033 } 987 1034 } 988 1035 else 989 1036 { … … 1302 1349 return false; 1303 1350 } 1304 1351 1352 function isServerOnLobby() 1353 { 1354 return (g_IsController && g_Source == "lobby") ? true : false; 1355 } 1305 1356 1357 function sendRegisterGameStanza() 1358 { 1359 var selectedMapSize = getGUIObjectByName("mapSize").selected; 1360 var selectedVictoryCondition = getGUIObjectByName("victoryCondition").selected; 1306 1361 1362 var mapSize = getGUIObjectByName("mapSize").list_data[selectedMapSize]; 1363 var victoryCondition = getGUIObjectByName("victoryCondition").list[selectedVictoryCondition]; 1307 1364 1365 var numberOfPlayers = 0; 1366 for (var guid in g_PlayerAssignments) 1367 { 1368 numberOfPlayers++; 1369 } 1370 1371 var nbp = numberOfPlayers ? numberOfPlayers : 1; 1372 var tnbp = g_GameAttributes.settings.PlayerData.length; 1373 1374 gameData = { 1375 "name":g_ServerName, 1376 "mapName":g_GameAttributes.map, 1377 "mapSize":mapSize, 1378 "victoryCondition":victoryCondition, 1379 "nbp":nbp, 1380 "tnbp":tnbp 1381 }; 1382 Engine.SendRegisterGame(gameData); 1383 } -
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
248 248 style="StoneButton" 249 249 size="100%-164 100%-52 100%-24 100%-24" 250 250 tooltip_style="onscreenToolTip" 251 tooltip="Return to the main menu."252 251 > 253 Main menu254 252 <action on="Press"> 255 253 <![CDATA[ 256 254 cancelSetup(); 255 if(isServerOnLobby()) Engine.SendUnregisterGame(g_ServerName); 257 256 Engine.PopGuiPage(); 258 257 ]]> 259 258 </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/lobby/styles.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <styles> 4 <style name="ChatPanel" 5 buffer_zone="5" 6 font="serif-13" 7 scrollbar="true" 8 scrollbar_style="wheatScrollBar" 9 scroll_bottom="true" 10 textcolor="white" 11 textcolor_selected="gold" 12 text_align="left" 13 text_valign="center" 14 /> 15 16 <style name="MapDescription" 17 buffer_zone="8" 18 font="serif-12" 19 scrollbar="true" 20 scrollbar_style="wheatScrollBar" 21 scroll_bottom="true" 22 textcolor="white" 23 text_align="left" 24 text_valign="top" 25 /> 26 27 <style name="SmallStoneDropDown" 28 dropdown_buffer="1" 29 font="serif-14" 30 textcolor="white" 31 text_align="center" 32 text_valign="center" 33 34 sprite="StoneButton" 35 sprite_over="StoneButtonOver" 36 sprite_pressed="StoneButtonGlow" 37 38 button_width="15" 39 sprite2="StoneArrowDn" 40 sprite2_pressed="StoneArrowDnOver" 41 42 buffer_zone="5" 43 dropdown_size="200" 44 sprite_list="BackgroundListBox" 45 sprite_selectarea="BackgroundSelectArea" 46 textcolor_selected="white" 47 48 scrollbar="true" 49 scrollbar_style="wheatScrollBar" 50 /> 51 52 </styles> -
binaries/data/mods/public/gui/lobby/lobby.js
1 var g_ChatMessages = []; 2 var g_Name = "unknown Bob"; 3 var g_GameList = {}; 4 5 //////////////////////////////////////////////////////////////////////////////////////////////// 6 var g_mapSizes = {}; 7 8 function init(attribs) 9 { 10 if (attribs.name) g_Name = attribs.name; 11 else error("No name"); 12 13 g_mapSizes = initMapSizes(); 14 g_mapSizes.names.push("Any"); 15 g_mapSizes.tiles.push(""); 16 17 var mapSizeFilter = getGUIObjectByName("mapSizeFilter"); 18 mapSizeFilter.list = g_mapSizes.names; 19 mapSizeFilter.list_data = g_mapSizes.tiles; 20 21 var playersNumberFilter = getGUIObjectByName("playersNumberFilter"); 22 playersNumberFilter.list = [2,3,4,5,6,7,8,"Any"]; 23 playersNumberFilter.list_data = [2,3,4,5,6,7,8,""]; 24 25 var victoryConditionFilter = getGUIObjectByName("victoryConditionFilter"); 26 victoryConditionFilter.list = ["Conquest","Any"]; 27 victoryConditionFilter.list_data = ["conquest",""]; 28 } 29 30 //////////////////////////////////////////////////////////////////////////////////////////////// 31 // Xmpp client connection management 32 //////////////////////////////////////////////////////////////////////////////////////////////// 33 34 35 function lobbyStop() 36 { 37 Engine.StopXmppClient(); 38 } 39 40 function lobbyConnect() 41 { 42 Engine.ConnectXmppClient(); 43 } 44 45 function lobbyDisconnect() 46 { 47 Engine.DisconnectXmppClient(); 48 } 49 50 //////////////////////////////////////////////////////////////////////////////////////////////// 51 // Server requests functions 52 //////////////////////////////////////////////////////////////////////////////////////////////// 53 54 function lobbyRefreshGameList() 55 { 56 Engine.SendGetGameList(); 57 } 58 59 //////////////////////////////////////////////////////////////////////////////////////////////// 60 // Update functions 61 //////////////////////////////////////////////////////////////////////////////////////////////// 62 63 var g_mapSizeFilter = ""; 64 var g_playersNumberFilter = ""; 65 var g_victoryConditionFilter = ""; 66 var g_hideFullFilter = false; 67 68 function resetFilters() 69 { 70 g_mapSizeFilter = ""; 71 g_playersNumberFilter = ""; 72 g_victoryConditionFilter = ""; 73 g_hideFullFilter = false; 74 getGUIObjectByName("mapSizeFilter").selected = -1; 75 getGUIObjectByName("playersNumberFilter").selected = -1; 76 getGUIObjectByName("victoryConditionFilter").selected = -1; 77 getGUIObjectByName("hideFullFilter").checked = false; 78 } 79 80 function setFilters() 81 { 82 var mapSizeFilter = getGUIObjectByName("mapSizeFilter"); 83 var playersNumberFilter = getGUIObjectByName("playersNumberFilter"); 84 var victoryConditionFilter = getGUIObjectByName("victoryConditionFilter"); 85 var hideFullFilter = getGUIObjectByName("hideFullFilter"); 86 87 g_mapSizeFilter = mapSizeFilter.selected >= 0 ? mapSizeFilter.list_data[mapSizeFilter.selected] : ""; 88 g_playersNumberFilter = playersNumberFilter.selected >=0 ? playersNumberFilter.list_data[playersNumberFilter.selected] : ""; 89 g_victoryConditionFilter = victoryConditionFilter.selected >= 0 ? victoryConditionFilter.list_data[victoryConditionFilter.selected] : ""; 90 g_hideFullFilter = hideFullFilter.checked ? true : false; 91 } 92 93 function displayGame(g) 94 { 95 if(g_mapSizeFilter != "" && g.mapSize != g_mapSizeFilter) return false; 96 if(g_victoryConditionFilter != "" && g.victoryCondition != g_victoryConditionFilter) return false; 97 if(g_playersNumberFilter != "" && g.tnbp != g_playersNumberFilter) return false; 98 if(g_hideFullFilter && g.tnbp == g.nbp) return false; 99 100 return true; 101 } 102 103 function updateGameList() 104 { 105 var gamesBox = getGUIObjectByName("gamesBox"); 106 var gameList = Engine.GetGameList(); 107 //Store the game whole game list data so that we can access it later 108 //to update the game info panel. 109 g_GameList = gameList; 110 111 var list_name = []; 112 var list_ip = []; 113 var list_mapName = []; 114 var list_mapSize = []; 115 var list_victoryCondition = []; 116 var list_nPlayers = []; 117 var list = []; 118 var list_data = []; 119 120 var c = 0; 121 for each (g in gameList) 122 { 123 if(displayGame(g)) 124 { 125 list_name.push(toTitleCase(g.name)); 126 list_ip.push(g.ip); 127 list_mapName.push(toTitleCase(g.mapName)); 128 list_mapSize.push(tilesToMapSize(g.mapSize)); 129 list_victoryCondition.push(toTitleCase(g.victoryCondition)); 130 list_nPlayers.push(g.nbp + "/" +g.tnbp); 131 list.push(g.name); 132 list_data.push(c); 133 } 134 c++; 135 } 136 137 gamesBox.list_name = list_name; 138 gamesBox.list_ip = list_ip; 139 gamesBox.list_mapName = list_mapName; 140 gamesBox.list_mapSize = list_mapSize; 141 gamesBox.list_victoryCondition = list_victoryCondition; 142 gamesBox.list_nPlayers = list_nPlayers; 143 gamesBox.list = list; 144 gamesBox.list_data = list_data; 145 146 if (gamesBox.selected >= gamesBox.list_name.length) 147 gamesBox.selected = -1; 148 } 149 150 function updatePlayerList() 151 { 152 var playersBox = getGUIObjectByName("playersBox") 153 154 var playerList = Engine.GetPlayerList(); 155 var playerListNames = [ player.name for each (player in playerList) ]; 156 157 playersBox.list = playerListNames; 158 if (playersBox.selected >= playersBox.list.length) 159 playersBox.selected = -1; 160 } 161 162 function selectGame(selected) 163 { 164 if(selected == -1) 165 { 166 // Hide the game info panel if not game is selected 167 getGUIObjectByName("gameInfo").hidden = true; 168 getGUIObjectByName("gameInfoEmpty").hidden = false; 169 return; 170 } 171 172 // Show the game info panel if a game is selected 173 getGUIObjectByName("gameInfo").hidden = false; 174 getGUIObjectByName("gameInfoEmpty").hidden = true; 175 176 //Get the selected map's name 177 var gamesBox = getGUIObjectByName("gamesBox"); 178 var g = gamesBox.list_data[selected]; 179 var name = g_GameList[g].mapName; 180 getGUIObjectByName("sgMapName").caption = toTitleCase(name); 181 182 var mapData = null; 183 184 //Search the selectep map in the scenarios 185 var mapFiles = getXMLFileList("maps/scenarios/"); 186 for (var i = 0; i < mapFiles.length; ++i) 187 { 188 var file = mapFiles[i]; 189 if(name == file) 190 { 191 mapData = Engine.LoadMapSettings("maps/scenarios/"+file); 192 break; 193 } 194 } 195 196 //Search the selectep map in the scenarios 197 if(!mapData) 198 { 199 var mapFiles = getJSONFileList("maps/random/"); 200 for (var i = 0; i < mapFiles.length; ++i) 201 { 202 var file = mapFiles[i]; 203 if(name == file) 204 { 205 mapData = parseJSONData("maps/random/"+file+".json"); 206 } 207 } 208 } 209 210 if(!mapData) 211 { 212 log("Map '"+ name +"' not found"); 213 } 214 215 // Load the description from the map file, if there is one, and display it 216 var mapSettings = (mapData && mapData.settings ? deepcopy(mapData.settings) : {}); 217 var description = mapSettings.Description || "Sorry, no description available."; 218 getGUIObjectByName("sgMapDescription").caption = description; 219 220 // Set the number of players, the map size and the victory condition text boxes 221 getGUIObjectByName("sgNbPlayers").caption = g_GameList[g].nbp + "/" + g_GameList[g].tnbp; 222 getGUIObjectByName("sgMapSize").caption = tilesToMapSize(g_GameList[g].mapSize); 223 getGUIObjectByName("sgVictoryCondition").caption = toTitleCase(g_GameList[g].victoryCondition); 224 225 } 226 227 function joinSelectedGame() 228 { 229 var gamesBox = getGUIObjectByName("gamesBox"); 230 if (gamesBox.selected >= 0) 231 { 232 var g = gamesBox.list_data[gamesBox.selected]; 233 var sname = g_Name; 234 var sip = g_GameList[g].ip; 235 // Open Multiplayer connection window with join option. 236 Engine.PushGuiPage("page_gamesetup_mp.xml", { multiplayerGameType: "join", source: "lobby", name: sname, ip: sip }); 237 } 238 } 239 240 //////////////////////////////////////////////////////////////////////////////////////////////// 241 // Utils 242 //////////////////////////////////////////////////////////////////////////////////////////////// 243 function tilesToMapSize(tiles) 244 { 245 var s = g_mapSizes.tiles.indexOf(Number(tiles)); 246 return s != -1 ? g_mapSizes.names[s].split(" ")[0] : "?"; 247 } 248 249 function twoDigits(n) 250 { 251 return n < 10 ? "0" + n : n; 252 } 253 254 //////////////////////////////////////////////////////////////////////////////////////////////// 255 // GUI event handlers 256 //////////////////////////////////////////////////////////////////////////////////////////////// 257 258 function onTick() 259 { 260 //Wake up XmppClient 261 Engine.RecvXmppClient(); 262 263 //Receive messages 264 while (true) 265 { 266 var message = Engine.LobbyGuiPollMessage(); 267 if (!message) 268 break; 269 switch (message.type) 270 { 271 case "mucmessage": 272 addChatMessage({ "from": message.from, "text": message.text , "color": "50 50 50"}); 273 break; 274 case "system": 275 switch (message.level) 276 { 277 case "standard": 278 addChatMessage({ "from": "system", "text": message.text, "color": "0 150 0" }); 279 break; 280 case "error": 281 addChatMessage({ "from": "system", "text": message.text, "color": "150 0 0" }); 282 if (message.text == "disconnected") 283 { 284 updateGameList(); 285 updatePlayerList(); 286 } 287 break; 288 case "internal": 289 switch (message.text) 290 { 291 case "gamelist updated": 292 updateGameList(); 293 var t = new Date(Date.now()); 294 var time = twoDigits(t.getUTCHours())+":"+twoDigits(t.getUTCMinutes())+":"+twoDigits(t.getUTCSeconds()); 295 getGUIObjectByName("updateStatusText").caption = "Updated at " + time; 296 break; 297 case "playerlist updated": 298 updatePlayerList(); 299 break; 300 } 301 break 302 } 303 break; 304 default: 305 error("Unrecognised message type "+message.type); 306 } 307 } 308 } 309 310 /* Messages */ 311 function submitChatInput() 312 { 313 var input = getGUIObjectByName("chatInput"); 314 var text = input.caption; 315 if (text.length) 316 { 317 Engine.LobbySendMessage(text); 318 input.caption = ""; 319 } 320 } 321 322 function handleMessage(message) 323 { 324 325 } 326 327 function pp(txt) 328 { 329 addChatMessage({"from":"debug", "color":"200 0 0", "text":txt}); 330 } 331 332 function addChatMessage(msg) 333 { 334 var from = escapeText(msg.from); 335 var text = escapeText(msg.text); 336 var color = msg.color; 337 338 var formatted = '[font="serif-bold-13"]<[color="'+ color +'"]' + from + '[/color]>[/font] ' + text; 339 g_ChatMessages.push(formatted); 340 getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); 341 } -
binaries/data/mods/public/gui/lobby/lobby.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <objects> 4 <script file="gui/lobby/lobby.js"/> 5 6 <script file="gui/common/functions_global_object.js"/> 7 <script file="gui/common/functions_utility.js"/> 8 9 <object type="image" style="StoneWindow" size="0 0 100% 100%" name="lobbyWindow"> 10 11 <object style="TitleText" type="text" size="50%-128 0%+4 50%+128 36"> 12 Multiplayer Lobby 13 </object> 14 15 <action on="Tick"> 16 onTick(); 17 </action> 18 19 <object size="25 50 100%-25 0%+400"> 20 <object name="gameInfoEmpty" size="0 0 340 100%-10" type="image" sprite="BackgroundIndentFillDark" hidden="false"> 21 <object size="50%-110 50%-50 50%+110 50%+50" type="image" sprite="productLogo"/> 22 </object> 23 <object name="gameInfo" size="0 0 340 100%-10" type="image" sprite="BackgroundIndentFillDark" hidden="true"> 24 <object name="sgMapName" size="170 10 100%-10 30" type="text" style="TitleText"/> 25 <object name="sgMapPicture" size="10 10 160 160" type="image" sprite="BackgroundIndentFillDark"/> 26 27 <!-- First Column --> 28 <object size="170 40 250 160"> 29 <!-- Number of Players--> 30 <object size="0 0 100% 32"> 31 <object size="0 0 100% 100%" type="text" style="LeftLabelText">Players:</object> 32 </object> 33 34 <object size="0 32 100% 64"> 35 <object size="0 0 100% 100%" type="text" style="LeftLabelText">Map size:</object> 36 </object> 37 38 <object size="0 64 100% 96"> 39 <object size="0 0 100% 100%" type="text" style="LeftLabelText">Victory:</object> 40 </object> 41 </object> 42 43 <!-- Second Column --> 44 <object size="250 40 100%-10 160"> 45 <!-- Number of Players--> 46 <object size="0 0 100% 32"> 47 <object name="sgNbPlayers" size="0 0 100% 100%" type="text" style="LeftLabelText"/> 48 </object> 49 50 <object size="0 32 100% 64"> 51 <object name="sgMapSize" size="0 0 100% 100%" type="text" style="LeftLabelText"/> 52 </object> 53 54 <object size="0 64 100% 96"> 55 <object name="sgVictoryCondition" size="0 0 100% 100%" type="text" style="LeftLabelText"/> 56 </object> 57 </object> 58 59 <object type="image" sprite="BackgroundIndentFillDark" size="10 170 100%-10 100%-40"> 60 <object name="sgMapDescription" type="text" style="MapDescription" size="0 0 100% 100%"/> 61 </object> 62 63 <object type="button" style="StoneButton" size="100%-100 100%-30 100%-10 100%-10"> 64 Join 65 <action on="Press"> 66 <![CDATA[ 67 joinSelectedGame(); 68 ]]> 69 </action> 70 </object> 71 72 </object> 73 74 <object name="gamesBox" 75 style="StoneList" 76 type="olist" 77 size="350 0 100% 100%-50" 78 tooltip_style="pgFloatingToolTip" 79 sprite_heading="colour:0 0 0 255" 80 textcolor="210 100 0 255"> 81 <action on="SelectionChange"> selectGame(this.selected);</action> 82 <def id="name" heading="Name" color="0 60 0" width="200"/> 83 <def id="ip" heading="IP" color="0 128 128" width="170"/> 84 <def id="mapName" heading="Map name" color="128 128 128" width="150"/> 85 <def id="mapSize" heading="Map size" color="128 128 128" width="120"/> 86 <def id="victoryCondition" heading="Victory condition" color="0 128 128" width="140"/> 87 <def id="nPlayers" heading="Players" color="0 128 128" width="30"/> 88 </object> 89 90 <object name="filterPanel" size="380 100%-140 870 100%-10" type="image" sprite="BackgroundIndentFillDark" hidden="true"> 91 <object type="text" size="10 10 110 30" text_align="left" textcolor="white">Map size :</object> 92 <object name="mapSizeFilter" 93 type="dropdown" 94 style="SmallStoneDropDown" 95 size="120 10 310 30"> 96 <action on="SelectionChange"><!--selectMapSize(this.list_data[this.selected]);--></action> 97 </object> 98 99 <object type="text" size="10 40 150 60" text_align="left" textcolor="white">Number of players :</object> 100 <object name="playersNumberFilter" 101 type="dropdown" 102 style="SmallStoneDropDown" 103 size="160 40 310 60"> 104 <action on="SelectionChange"></action> 105 </object> 106 107 <object type="text" size="10 70 150 90" text_align="left" textcolor="white">Victory condition :</object> 108 <object name="victoryConditionFilter" 109 type="dropdown" 110 style="SmallStoneDropDown" 111 size="160 70 310 90"> 112 <action on="SelectionChange"></action> 113 </object> 114 115 <object type="text" size="10 100 150 120" text_align="left" textcolor="white">Hide full games :</object> 116 <object name="hideFullFilter" 117 type="checkbox" 118 style="StoneCrossBox" 119 size="160 105 310 120"> 120 <action on="SelectionChange"></action> 121 </object> 122 123 <object type="button" style="StoneButton" size="100%-230 100%-30 100%-130 100%-10"> 124 Reset 125 <action on="Press"> <![CDATA[resetFilters();updateGameList();]]></action> 126 </object> 127 128 <object type="button" style="StoneButton" size="100%-110 100%-30 100%-10 100%-10"> 129 Filter 130 <action on="Press"> <![CDATA[setFilters();updateGameList();]]></action> 131 </object> 132 133 </object> 134 135 <object name="gamesBar" size="350 100%-40 100% 100%"> 136 <object type="button" style="StoneButton" size="0 0 20 20"> 137 >> 138 <action on="Press"><![CDATA[ 139 if(this.caption == ">>") 140 { 141 this.caption = "<<"; 142 getGUIObjectByName("filterPanel").hidden = false; 143 getGUIObjectByName("gamesBox").size="350 0 100% 100%-150"; 144 } 145 else 146 { 147 this.caption = ">>"; 148 getGUIObjectByName("filterPanel").hidden = true; 149 getGUIObjectByName("gamesBox").size="350 0 100% 100%-50"; 150 } 151 ]]> 152 </action> 153 </object> 154 155 <object name="updateStatusText" size="100%-440 0 100%-240 20" type="text" style="RightLabelText"/> 156 157 <object type="button" style="StoneButton" size="100%-220 0 100%-120 20"> 158 Update 159 <action on="Press"> lobbyRefreshGameList();</action> 160 </object> 161 162 <object type="button" style="StoneButton" size="100%-100 0 100% 20"> 163 Host Game 164 <action on="Press"> 165 <![CDATA[ 166 var sname = g_Name; 167 // Open Multiplayer connection window with host option. 168 Engine.PushGuiPage("page_gamesetup_mp.xml", { multiplayerGameType: "host", source: "lobby", name: sname }); 169 ]]> 170 </action> 171 </object> 172 173 </object> 174 </object> 175 176 <object size="25 0%+400 100%-25 100%-25"> 177 <object name="playersBox" 178 style="StoneList" 179 type="list" 180 size="100%-200 0 100% 100%-40" 181 tooltip_style="pgFloatingToolTip" 182 tooltip="Players."> 183 </object> 184 185 <object name="chatPanel" size="0 0 100%-220 100%-10" type="image" sprite="BackgroundIndentFillDark"> 186 <object name="chatText" size="3 1 100%-1 100%-25" type="text" style="ChatPanel"/> 187 <object name="chatInput" size="2 100%-23 100%-66 100%-3" type="input" style="StoneInput"> 188 <action on="Press">submitChatInput();</action> 189 </object> 190 191 <object size="100%-65 100%-25 100%-1 100%" type="button" style="StoneButton"> 192 Send 193 <action on="Press">submitChatInput();</action> 194 </object> 195 </object> 196 </object> 197 198 <object name="navBar" size="20 25 100%-20 45"> 199 <object type="button" style="StoneButton" size="100%-340 0 100%-240 20"> 200 Connect 201 <action on="Press">lobbyConnect();</action> 202 </object> 203 204 <object type="button" style="StoneButton" size="100%-220 0 100%-120 20"> 205 Disconnect 206 <action on="Press">lobbyDisconnect();</action> 207 </object> 208 209 <object type="button" style="StoneButton" size="100%-100 0 100% 20"> 210 Main Menu 211 <action on="Press"> 212 <![CDATA[ 213 lobbyStop(); 214 Engine.PopGuiPage(); 215 ]]> 216 </action> 217 </object> 218 </object> 219 220 </object> 221 </objects> -
binaries/data/mods/public/gui/lobby/prelobby.js
1 var g_LobbyIsConnecting = false; 2 var g_InitialUsername = ""; 3 var g_InitialPassword = ""; 4 5 function init() 6 { 7 g_InitialUsername = Engine.GetDefaultLobbyPlayerUsername(); 8 g_InitialPassword = Engine.GetDefaultLobbyPlayerPassword(); 9 } 10 11 function lobbyStop() 12 { 13 getGUIObjectByName("connectFeedback").caption = ""; 14 getGUIObjectByName("registerFeedback").caption = ""; 15 16 if (g_LobbyIsConnecting == false) 17 return; 18 19 g_LobbyIsConnecting = false; 20 Engine.StopXmppClient(); 21 } 22 23 function lobbyStart() 24 { 25 if (g_LobbyIsConnecting != false) 26 return; 27 28 var username = getGUIObjectByName("connectUsername").caption; 29 var password = getGUIObjectByName("connectPassword").caption; 30 var playername = getGUIObjectByName("joinPlayerName").caption; 31 var feedback = getGUIObjectByName("connectFeedback"); 32 33 if (!username || !password) 34 { 35 feedback.caption = "Username or password empty"; 36 } 37 else 38 { 39 feedback.caption = "Connecting.."; 40 Engine.StartXmppClient(username, password, "arena", playername); 41 g_LobbyIsConnecting=true; 42 Engine.ConnectXmppClient(); 43 } 44 } 45 46 function lobbyStartRegister() 47 { 48 if (g_LobbyIsConnecting != false) 49 return; 50 51 var account = getGUIObjectByName("registerUsername").caption; 52 var password = getGUIObjectByName("registerPassword").caption; 53 var passwordAgain = getGUIObjectByName("registerPasswordAgain").caption; 54 var feedback = getGUIObjectByName("registerFeedback"); 55 56 if (!account || !password || !passwordAgain) 57 { 58 feedback.caption = "Account name or password empty"; 59 } 60 else if (password != passwordAgain) 61 { 62 feedback.caption = "Password mismatch"; 63 getGUIObjectByName("registerPassword").caption = ""; 64 getGUIObjectByName("registerPasswordAgain").caption = ""; 65 } 66 else 67 { 68 feedback.caption = "Registering.."; 69 Engine.StartRegisterXmppClient( 70 account, 71 password); 72 g_LobbyIsConnecting=true; 73 Engine.ConnectXmppClient(); 74 } 75 } 76 77 function onTick() 78 { 79 if (!g_LobbyIsConnecting) 80 { 81 // The Xmpp Client has not been created 82 } 83 else 84 { 85 // The XmppClient has been created, we are waiting 86 // to be connected or to receive an error. 87 88 //Wake up XmppClient 89 Engine.RecvXmppClient(); 90 91 //Receive messages 92 while (true) 93 { 94 var message = Engine.LobbyGuiPollMessage(); 95 if (!message) 96 break; 97 98 if (message.type == "system" && message.text == "connected") 99 { 100 // We are connected, switch to the lobby page 101 Engine.PopGuiPage(); 102 var sname = getGUIObjectByName("joinPlayerName").caption; 103 Engine.PushGuiPage("page_lobby.xml", { name: sname } ); 104 105 var username = getGUIObjectByName("connectUsername").caption; 106 var password = getGUIObjectByName("connectPassword").caption; 107 // Store latest username and password if they changed 108 if(username != g_InitialUsername || password != g_InitialPassword) 109 { 110 Engine.SetDefaultLobbyPlayerPair(username, password); 111 } 112 113 return; 114 } 115 else if (message.type == "system" && message.text == "registered") 116 { 117 // Great, we are registered. Switch to the connection window. 118 getGUIObjectByName("registerFeedback").caption = message.text; 119 getGUIObjectByName("connectFeedback").caption = message.text; 120 Engine.StopXmppClient(); 121 g_LobbyIsConnecting = false; 122 getGUIObjectByName("connectUsername").caption = getGUIObjectByName("registerUsername").caption; 123 getGUIObjectByName("pageRegister").hidden = true; 124 getGUIObjectByName("pageConnect").hidden = false; 125 } 126 else if(message.type == "system" && message.level == "error") 127 { 128 getGUIObjectByName("connectFeedback").caption = message.text; 129 getGUIObjectByName("registerFeedback").caption = message.text; 130 Engine.StopXmppClient(); 131 g_LobbyIsConnecting = false; 132 } 133 } 134 } 135 } -
binaries/data/mods/public/gui/lobby/prelobby.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <objects> 4 <script file="gui/lobby/prelobby.js"/> 5 6 <script file="gui/common/functions_global_object.js"/> 7 <script file="gui/common/functions_utility.js"/> 8 9 <object name="dialog" type="image" style="StoneDialog" size="50%-190 50%-140 50%+190 50%+140"> 10 11 <action on="Tick"> 12 onTick(); 13 </action> 14 15 <object name="pageConnecting" hidden="true"> 16 <object name="connectionStatus" type="text" text_align="center" size="0 100 100% 120"> 17 [Connection status] 18 </object> 19 </object> 20 21 <object style="TitleText" type="text" size="50%-128 0%-16 50%+128 16"> 22 Multiplayer Lobby 23 </object> 24 25 <object name="pageConnect" size="0 32 100% 100%"> 26 <object type="text" style="CenteredLabelText" size="0 0 400 30"> 27 Connect to the game lobby. 28 </object> 29 <object type="text" size="0 40 200 70" style="RightLabelText"> 30 Player name: 31 </object> 32 <object name="joinPlayerName" type="input" size="210 40 100%-32 64" style="StoneInput"> 33 <action on="Load"><![CDATA[ 34 this.caption = Engine.GetDefaultPlayerName(); 35 ]]></action> 36 </object> 37 <object type="text" size="0 80 200 110" style="RightLabelText"> 38 0ad xmpp id: 39 </object> 40 <object name="connectUsername" type="input" size="210 80 100%-32 104" style="StoneInput"> 41 <action on="Load"><![CDATA[ 42 this.caption = Engine.GetDefaultLobbyPlayerUsername(); 43 ]]></action> 44 </object> 45 <object type="text" size="0 120 200 150" style="RightLabelText"> 46 Password: 47 </object> 48 <object name="connectPassword" type="input" size="210 120 100%-32 144" style="StoneInput"> 49 <action on="Load"><![CDATA[ 50 this.caption = Engine.GetDefaultLobbyPlayerPassword(); 51 ]]></action> 52 </object> 53 <object name="connectFeedback" type="text" style="CenteredLabelText" size="32 150 100%-32 180" textcolor="red"/> 54 <object type="button" size="32 100%-60 122 100%-32" style="StoneButton"> 55 Cancel 56 <action on="Press"><![CDATA[ 57 lobbyStop(); 58 Engine.PopGuiPage(); 59 ]]></action> 60 </object> 61 <object type="button" size="145 100%-60 235 100%-32" style="StoneButton"> 62 Register 63 <action on="Press"><![CDATA[ 64 lobbyStop(); 65 getGUIObjectByName("pageConnect").hidden = true; 66 getGUIObjectByName("pageRegister").hidden = false; 67 ]]></action> 68 </object> 69 <object type="button" size="258 100%-60 100%-32 100%-32" style="StoneButton"> 70 Connect 71 <action on="Press"><![CDATA[ 72 lobbyStart(); 73 ]]></action> 74 </object> 75 </object> 76 77 <object name="pageRegister" size="0 32 100% 100%" hidden="true"> 78 <object type="text" style="CenteredLabelText" size="0 0 400 30"> 79 Register to the game lobby. 80 </object> 81 <object type="text" size="0 40 200 70" style="RightLabelText"> 82 Account name: 83 </object> 84 <object name="registerUsername" type="input" size="210 40 100%-32 64" style="StoneInput"> 85 </object> 86 <object type="text" size="0 80 200 110" style="RightLabelText"> 87 Password: 88 </object> 89 <object name="registerPassword" type="input" size="210 80 100%-32 104" style="StoneInput"> 90 </object> 91 <object type="text" size="0 120 200 150" style="RightLabelText"> 92 Password again: 93 </object> 94 <object name="registerPasswordAgain" type="input" size="210 120 100%-32 144" style="StoneInput"> 95 </object> 96 <object name="registerFeedback" type="text" style="CenteredLabelText" size="32 150 100%-32 180" textcolor="red"/> 97 <object type="button" size="32 100%-60 122 100%-32" style="StoneButton"> 98 Back 99 <action on="Press"><![CDATA[ 100 lobbyStop(); 101 getGUIObjectByName("pageRegister").hidden = true; 102 getGUIObjectByName("pageConnect").hidden = false; 103 ]]></action> 104 </object> 105 <object type="button" size="258 100%-60 100%-32 100%-32" style="StoneButton"> 106 Register 107 <action on="Press"><![CDATA[ 108 lobbyStartRegister() 109 ]]></action> 110 </object> 111 </object> 112 113 </object> 114 115 </objects> -
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"