Merge pull request #306 from Wargus/tim/pvpgn
Support pvpgn for online multiplayer
This commit is contained in:
commit
d4919270ca
14 changed files with 2858 additions and 404 deletions
|
@ -232,10 +232,10 @@ set(network_SRCS
|
|||
src/network/commands.cpp
|
||||
src/network/net_lowlevel.cpp
|
||||
src/network/net_message.cpp
|
||||
src/network/master.cpp
|
||||
src/network/netconnect.cpp
|
||||
src/network/network.cpp
|
||||
src/network/netsockets.cpp
|
||||
src/network/online_service.cpp
|
||||
)
|
||||
source_group(network FILES ${network_SRCS})
|
||||
|
||||
|
@ -365,7 +365,6 @@ set(tolua_FILES
|
|||
src/tolua/font.pkg
|
||||
src/tolua/game.pkg
|
||||
src/tolua/map.pkg
|
||||
src/tolua/master.pkg
|
||||
src/tolua/minimap.pkg
|
||||
src/tolua/network.pkg
|
||||
src/tolua/particle.pkg
|
||||
|
@ -526,6 +525,7 @@ set(stratagus_generic_HDRS
|
|||
src/include/cursor.h
|
||||
src/include/depend.h
|
||||
src/include/editor.h
|
||||
src/include/online_service.h
|
||||
src/include/font.h
|
||||
src/include/game.h
|
||||
src/include/icons.h
|
||||
|
@ -534,7 +534,6 @@ set(stratagus_generic_HDRS
|
|||
src/include/iolib.h
|
||||
src/include/luacallback.h
|
||||
src/include/map.h
|
||||
src/include/master.h
|
||||
src/include/menus.h
|
||||
src/include/minimap.h
|
||||
src/include/missile.h
|
||||
|
@ -1101,43 +1100,6 @@ endif()
|
|||
|
||||
########### next target ###############
|
||||
|
||||
set(metaserver_SRCS
|
||||
metaserver/cmd.cpp
|
||||
metaserver/db.cpp
|
||||
metaserver/games.cpp
|
||||
metaserver/main.cpp
|
||||
metaserver/netdriver.cpp
|
||||
src/network/net_lowlevel.cpp
|
||||
)
|
||||
|
||||
set(metaserver_HDRS
|
||||
metaserver/cmd.h
|
||||
metaserver/db.h
|
||||
metaserver/games.h
|
||||
metaserver/netdriver.h
|
||||
)
|
||||
|
||||
source_group(metaserver FILES ${metaserver_SRCS} ${metaserver_HDRS})
|
||||
|
||||
if(SQLITE_FOUND)
|
||||
add_executable(metaserver ${metaserver_SRCS} ${metaserver_HDRS})
|
||||
target_link_libraries(metaserver ${SDL2_LIBRARY} ${SQLITE_LIBRARIES})
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(metaserver winmm ws2_32)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND MINGW)
|
||||
target_link_libraries(metaserver dxguid)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND MINGW AND ENABLE_STATIC)
|
||||
set_target_properties(metaserver PROPERTIES LINK_FLAGS "${LINK_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set(png2stratagus_SRCS
|
||||
tools/png2stratagus.cpp
|
||||
)
|
||||
|
@ -1172,8 +1134,6 @@ set(doxygen_FILES
|
|||
doc/Doxyfile-header.html
|
||||
${stratagus_SRCS}
|
||||
${stratagus_HDRS}
|
||||
${metaserver_SRCS}
|
||||
${metaserver_HDRS}
|
||||
${gameheaders_HDRS}
|
||||
${png2stratagus_SRCS}
|
||||
)
|
||||
|
@ -1208,9 +1168,6 @@ endmacro()
|
|||
if(ENABLE_UPX AND SELF_PACKER_FOR_EXECUTABLE)
|
||||
self_packer(stratagus)
|
||||
self_packer(png2stratagus)
|
||||
if(SQLITE_FOUND)
|
||||
self_packer(metaserver)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
########### next target ###############
|
||||
|
@ -1235,10 +1192,6 @@ endif()
|
|||
install(TARGETS stratagus DESTINATION ${GAMEDIR})
|
||||
install(TARGETS png2stratagus DESTINATION ${BINDIR})
|
||||
|
||||
if(SQLITE_FOUND)
|
||||
install(TARGETS metaserver DESTINATION ${BINDIR} RENAME stratagus-metaserver)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DOC AND DOXYGEN_FOUND)
|
||||
install(FILES doc/stratagus.6 DESTINATION ${MANDIR})
|
||||
install(FILES
|
||||
|
@ -1250,7 +1203,6 @@ if(ENABLE_DOC AND DOXYGEN_FOUND)
|
|||
doc/index.html
|
||||
doc/install.html
|
||||
doc/media.html
|
||||
doc/metaserver_protocol.txt
|
||||
doc/README-SDL.txt
|
||||
DESTINATION share/doc/stratagus
|
||||
)
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "missile.h"
|
||||
#include "netconnect.h"
|
||||
#include "network.h"
|
||||
#include "online_service.h"
|
||||
#include "parameters.h"
|
||||
#include "pathfinder.h"
|
||||
#include "player.h"
|
||||
|
@ -1507,6 +1508,7 @@ void LuaRegisterModules()
|
|||
UpgradesCclRegister();
|
||||
UserInterfaceCclRegister();
|
||||
VideoCclRegister();
|
||||
OnlineServiceCclRegister();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name master.h - The master server headerfile. */
|
||||
//
|
||||
// (c) Copyright 2003-2007 by Tom Zickel and Jimmy Salmon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; only version 2 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
#ifndef __MASTER_H__
|
||||
#define __MASTER_H__
|
||||
|
||||
//@{
|
||||
|
||||
#include <list>
|
||||
#include "network/netsockets.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Declarations
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
struct lua_State;
|
||||
|
||||
// Log data used in metaserver client
|
||||
struct CClientLog {
|
||||
std::string entry; // command itself
|
||||
};
|
||||
|
||||
|
||||
// Class representing meta server client structure
|
||||
class CMetaClient
|
||||
{
|
||||
public:
|
||||
CMetaClient() : metaSocket(), metaPort(-1), lastRecvState(-1) {}
|
||||
~CMetaClient();
|
||||
void SetMetaServer(const std::string host, const int port);
|
||||
int Init();
|
||||
void Close();
|
||||
int Send(const std::string cmd);
|
||||
int Recv();
|
||||
int GetLastRecvState() { return lastRecvState; }
|
||||
int GetLogSize() { return events.size(); }
|
||||
CClientLog *GetLastMessage() { return events.back(); }
|
||||
int CreateGame(std::string desc, std::string map, std::string players);
|
||||
|
||||
private:
|
||||
CTCPSocket metaSocket; /// This is a TCP socket
|
||||
std::string metaHost; /// Address of metaserver
|
||||
int metaPort; /// Port of metaserver
|
||||
std::list <CClientLog *> events; /// All commands received from metaserver
|
||||
int lastRecvState; /// Now many bytes have been received in last reply
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
----------------------------------------------------------------------------*/
|
||||
// Metaserver itself
|
||||
extern CMetaClient MetaClient;
|
||||
|
||||
//@}
|
||||
|
||||
#endif // !__MASTER_H__
|
|
@ -32,6 +32,7 @@
|
|||
//@{
|
||||
|
||||
#include "net_message.h"
|
||||
#include "network/netsockets.h"
|
||||
|
||||
class CHost;
|
||||
|
||||
|
@ -97,9 +98,13 @@ extern int NetConnectType; /// Network menu: Setup mode active
|
|||
extern int NetLocalHostsSlot; /// Network menu: Slot # in Hosts array of local client
|
||||
extern int NetLocalPlayerNumber; /// Player number of local client
|
||||
|
||||
extern std::string NetworkMapName; /// Name of the map received with ICMMap
|
||||
|
||||
extern CServerSetup ServerSetupState; /// Network menu: Multiplayer Server Menu selections state
|
||||
extern CServerSetup LocalSetupState; /// Network menu: Multiplayer Client Menu selections local state
|
||||
|
||||
extern int NoRandomPlacementMultiplayer; /// Disable the random placement of players in muliplayer mode
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
@ -119,6 +124,8 @@ extern void NetworkProcessServerRequest(); /// Menu Loop: Send out server reque
|
|||
extern void NetworkServerResyncClients(); /// Menu Loop: Server: Mark clients state to send stateinfo message
|
||||
extern void NetworkDetachFromServer(); /// Menu Loop: Client: Send GoodBye to the server and detach
|
||||
|
||||
extern void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const CInitMessage_Header &msg);
|
||||
|
||||
//@}
|
||||
|
||||
#endif // !__NETCONNECT_H__
|
||||
|
|
38
src/include/online_service.h
Normal file
38
src/include/online_service.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef __ONLINE_SERVICE_H__
|
||||
#define __ONLINE_SERVICE_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "network/netsockets.h"
|
||||
|
||||
class OnlineContext {
|
||||
public:
|
||||
virtual ~OnlineContext() { };
|
||||
|
||||
// called in the sdl event loop
|
||||
virtual bool handleUDP(const unsigned char *buffer, int len, CHost host) = 0;
|
||||
|
||||
// called in the sdl event loop
|
||||
virtual void doOneStep() = 0;
|
||||
|
||||
// called when joining a network game
|
||||
virtual void joinGame(std::string hostPlayerName, std::string pw) = 0;
|
||||
|
||||
// called when leaving a network game
|
||||
virtual void leaveGame() = 0;
|
||||
|
||||
// called when advertised game is starting (just reports the game as in-progress)
|
||||
virtual void startAdvertising(bool isStarted = false) = 0;
|
||||
|
||||
// called when advertised game is left by the server
|
||||
virtual void stopAdvertising() = 0;
|
||||
|
||||
// called when network game ends
|
||||
virtual void reportGameResult() = 0;
|
||||
};
|
||||
|
||||
extern OnlineContext *OnlineContextHandler;
|
||||
|
||||
extern void OnlineServiceCclRegister();
|
||||
|
||||
#endif
|
|
@ -1,244 +0,0 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name master.cpp - The master server. */
|
||||
//
|
||||
// (c) Copyright 2003-2007 by Tom Zickel and Jimmy Salmon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; only version 2 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
#include "master.h"
|
||||
|
||||
#include "game.h"
|
||||
#include "network/netsockets.h"
|
||||
#include "network.h"
|
||||
#include "net_lowlevel.h"
|
||||
#include "parameters.h"
|
||||
#include "script.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
CMetaClient MetaClient;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Set the metaserver to use for internet play.
|
||||
**
|
||||
** @param host Host to connect
|
||||
** @param port Port to use to connect
|
||||
*/
|
||||
void CMetaClient::SetMetaServer(const std::string host, const int port)
|
||||
{
|
||||
metaHost = host;
|
||||
metaPort = port;
|
||||
}
|
||||
|
||||
CMetaClient::~CMetaClient()
|
||||
{
|
||||
for (std::list<CClientLog *>::iterator it = events.begin(); it != events.end(); ++it) {
|
||||
CClientLog *log = *it;
|
||||
delete log;
|
||||
}
|
||||
events.clear();
|
||||
this->Close();
|
||||
}
|
||||
|
||||
/**
|
||||
** Initialize the TCP connection to the Meta Server and send test ping to it.
|
||||
**
|
||||
** @return -1 fail, 0 success.
|
||||
*/
|
||||
int CMetaClient::Init()
|
||||
{
|
||||
if (metaPort == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Server socket
|
||||
CHost metaServerHost(metaHost.c_str(), metaPort);
|
||||
// Client socket
|
||||
|
||||
// open on all interfaces, not the loopback, unless we have an override from the commandline
|
||||
std::string localHost = CNetworkParameter::Instance.localHost;
|
||||
if (!localHost.compare("127.0.0.1")) {
|
||||
localHost = "0.0.0.0";
|
||||
}
|
||||
CHost metaClientHost(localHost.c_str(), CNetworkParameter::Instance.localPort);
|
||||
metaSocket.Open(metaClientHost);
|
||||
if (metaSocket.IsValid() == false) {
|
||||
fprintf(stderr, "METACLIENT: No free port %d available, aborting\n", metaServerHost.getPort());
|
||||
return -1;
|
||||
}
|
||||
if (metaSocket.Connect(metaServerHost) == false) {
|
||||
fprintf(stderr, "METACLIENT: Unable to connect to host %s\n", metaServerHost.toString().c_str());
|
||||
MetaClient.Close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this->Send("PING") == -1) { // not sent
|
||||
MetaClient.Close();
|
||||
return -1;
|
||||
}
|
||||
if (this->Recv() == -1) { // not received
|
||||
MetaClient.Close();
|
||||
return -1;
|
||||
}
|
||||
CClientLog &log = *GetLastMessage();
|
||||
if (log.entry.find("PING_OK") != std::string::npos) {
|
||||
// Everything is OK
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "METACLIENT: inappropriate message received from %s\n", metaServerHost.toString().c_str());
|
||||
MetaClient.Close();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Close Connection to Master Server
|
||||
**
|
||||
** @return nothing
|
||||
*/
|
||||
void CMetaClient::Close()
|
||||
{
|
||||
if (metaSocket.IsValid()) {
|
||||
metaSocket.Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Send a command to the meta server
|
||||
**
|
||||
** @param cmd command to send
|
||||
**
|
||||
** @returns -1 if failed, otherwise length of command
|
||||
*/
|
||||
int CMetaClient::Send(const std::string cmd)
|
||||
{
|
||||
int ret = -1;
|
||||
if (metaSocket.IsValid()) {
|
||||
std::string mes(cmd);
|
||||
mes.append("\n");
|
||||
ret = metaSocket.Send(mes.c_str(), mes.size());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
** Receive reply from Meta Server
|
||||
**
|
||||
** @return error or number of bytes
|
||||
*/
|
||||
int CMetaClient::Recv()
|
||||
{
|
||||
if (metaSocket.HasDataToRead(5000) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
int n = metaSocket.Recv(&buf, sizeof(buf));
|
||||
if (n == -1) {
|
||||
return n;
|
||||
}
|
||||
// We know we now have the whole command.
|
||||
// Convert to standard notation
|
||||
std::string cmd(buf, strlen(buf));
|
||||
cmd += '\n';
|
||||
cmd += '\0';
|
||||
CClientLog *log = new CClientLog;
|
||||
log->entry = cmd;
|
||||
events.push_back(log);
|
||||
lastRecvState = n;
|
||||
return n;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
int CMetaClient::CreateGame(std::string desc, std::string map, std::string players) {
|
||||
if (metaSocket.IsValid() == false) {
|
||||
return -1;
|
||||
}
|
||||
if (NetworkFildes.IsValid() == false) {
|
||||
return -1;
|
||||
}
|
||||
CHost metaServerHost(metaHost.c_str(), metaPort);
|
||||
|
||||
// Advertise an external IP address if we can
|
||||
unsigned long ips[1];
|
||||
int networkNumInterfaces = NetworkFildes.GetSocketAddresses(ips, 1);
|
||||
std::string ipport = "";
|
||||
if (!networkNumInterfaces || CNetworkParameter::Instance.localHost.compare("127.0.0.1")) {
|
||||
ipport += CNetworkParameter::Instance.localHost.c_str();
|
||||
} else {
|
||||
ipport += inet_ntoa(((struct in_addr *)ips)[0]);
|
||||
}
|
||||
ipport += " ";
|
||||
ipport += std::to_string(CNetworkParameter::Instance.localPort);
|
||||
|
||||
std::string cmd("CREATEGAME \"");
|
||||
cmd += desc;
|
||||
cmd += "\" \"";
|
||||
cmd += map;
|
||||
cmd += "\" ";
|
||||
cmd += players;
|
||||
cmd += " ";
|
||||
cmd += ipport;
|
||||
|
||||
if (this->Send(cmd.c_str()) == -1) { // not sent
|
||||
return -1;
|
||||
}
|
||||
if (this->Recv() == -1) { // not received
|
||||
return -1;
|
||||
}
|
||||
CClientLog &log = *GetLastMessage();
|
||||
if (log.entry.find("CREATEGAME_OK") != std::string::npos) {
|
||||
// Everything is OK, let's inform metaserver of our UDP info
|
||||
NetworkFildes.Send(metaServerHost, ipport.c_str(), ipport.size());
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "METACLIENT: failed to create game: %s\n", log.entry.c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -33,13 +33,13 @@
|
|||
// Includes
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "online_service.h"
|
||||
#include "stratagus.h"
|
||||
|
||||
#include "netconnect.h"
|
||||
|
||||
#include "interface.h"
|
||||
#include "map.h"
|
||||
#include "master.h"
|
||||
#include "network.h"
|
||||
#include "parameters.h"
|
||||
#include "player.h"
|
||||
|
@ -87,7 +87,7 @@ int NetLocalPlayerNumber; /// Player number of local client
|
|||
|
||||
int NetPlayers; /// How many network players
|
||||
std::string NetworkMapName; /// Name of the map received with ICMMap
|
||||
static int NoRandomPlacementMultiplayer = 0; /// Disable the random placement of players in muliplayer mode
|
||||
int NoRandomPlacementMultiplayer = 0; /// Disable the random placement of players in muliplayer mode
|
||||
|
||||
CServerSetup ServerSetupState; // Server selection state for Multiplayer clients
|
||||
CServerSetup LocalSetupState; // Local selection state for Multiplayer clients
|
||||
|
@ -782,6 +782,8 @@ void CClient::Parse_Welcome(const unsigned char *buf)
|
|||
CNetworkParameter::Instance.NetworkLag = msg.Lag;
|
||||
CNetworkParameter::Instance.gameCyclesPerUpdate = msg.gameCyclesPerUpdate;
|
||||
|
||||
OnlineContextHandler->joinGame(msg.hosts[0].PlyName, "");
|
||||
|
||||
Hosts[0].Host = serverHost.getIp();
|
||||
Hosts[0].Port = serverHost.getPort();
|
||||
for (int i = 1; i < PlayerMax; ++i) {
|
||||
|
@ -1706,6 +1708,10 @@ breakout:
|
|||
}
|
||||
|
||||
DebugPrint("DONE: All configs acked - Now starting..\n");
|
||||
|
||||
// advertise online that we're in progress
|
||||
OnlineContextHandler->startAdvertising(true);
|
||||
|
||||
// Give clients a quick-start kick..
|
||||
const CInitMessage_Header message_go(MessageInit_FromServer, ICMGo);
|
||||
for (int i = 0; i < HostsCount; ++i) {
|
||||
|
|
|
@ -219,6 +219,7 @@
|
|||
// Includes
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "online_service.h"
|
||||
#include "stratagus.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
@ -403,6 +404,9 @@ static void NetworkSendPacket(const CNetworkCommandQueue(&ncq)[MaxNetworkCommand
|
|||
*/
|
||||
void InitNetwork1()
|
||||
{
|
||||
if (NetworkFildes.IsValid()) {
|
||||
return;
|
||||
}
|
||||
CNetworkParameter::Instance.FixValues();
|
||||
|
||||
NetInit(); // machine dependent setup
|
||||
|
@ -863,6 +867,10 @@ void NetworkEvent()
|
|||
return;
|
||||
}
|
||||
|
||||
if (OnlineContextHandler->handleUDP(buf, len, host)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup messages
|
||||
if (NetConnectRunning) {
|
||||
if (NetworkParseSetupEvent(buf, len, host)) {
|
||||
|
|
2305
src/network/online_service.cpp
Normal file
2305
src/network/online_service.cpp
Normal file
File diff suppressed because it is too large
Load diff
478
src/network/xsha1.h
Normal file
478
src/network/xsha1.h
Normal file
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Stratagus Project
|
||||
* Copyright (C) 1999 Descolada (dyn1-tnt9-237.chicago.il.ameritech.net)
|
||||
* Copyright (C) 1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
/* valid for 0<=n and w>0 , depends on 2's complement */
|
||||
#define ROTL(x,n,w) (((x)<<((n)&(w-1))) | ((x)>>(((-(n))&(w-1)))))
|
||||
|
||||
/* valid for 0<=n and w>0 , uses three mods and an ugly conditional */
|
||||
/* FIXME: and also a bug because it doesn't work on PPC */
|
||||
/*#define ROTL(x,n,w) (((n)%(w)) ? (((x)<<((n)%(w))) | ((x)>>((w)-((n)%(w))))) : (x))*/
|
||||
|
||||
#define ROTL32(x,n) ROTL(x,n,32)
|
||||
#define ROTL16(x,n) ROTL(x,n,16)
|
||||
|
||||
|
||||
namespace pvpgn
|
||||
{
|
||||
using bn_basic = std::uint8_t;
|
||||
using bn_byte = bn_basic[1];
|
||||
using bn_short = bn_basic[2];
|
||||
using bn_int = bn_basic[4];
|
||||
using bn_long = bn_basic[8];
|
||||
using t_hash = std::uint32_t[5];
|
||||
|
||||
int bn_int_set(bn_int * dst, std::uint32_t src)
|
||||
{
|
||||
if (!dst)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*dst)[0] = (std::uint8_t)((src)& 0xff);
|
||||
(*dst)[1] = (std::uint8_t)((src >> 8) & 0xff);
|
||||
(*dst)[2] = (std::uint8_t)((src >> 16) & 0xff);
|
||||
(*dst)[3] = (std::uint8_t)((src >> 24));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bn_int_nset(bn_int * dst, std::uint32_t src)
|
||||
{
|
||||
if (!dst)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*dst)[0] = (std::uint8_t)((src >> 24));
|
||||
(*dst)[1] = (std::uint8_t)((src >> 16) & 0xff);
|
||||
(*dst)[2] = (std::uint8_t)((src >> 8) & 0xff);
|
||||
(*dst)[3] = (std::uint8_t)((src)& 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::uint32_t bn_int_get(bn_int const src)
|
||||
{
|
||||
std::uint32_t temp;
|
||||
|
||||
if (!src)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
temp = ((std::uint32_t)src[0]);
|
||||
temp |= ((std::uint32_t)src[1]) << 8;
|
||||
temp |= ((std::uint32_t)src[2]) << 16;
|
||||
temp |= ((std::uint32_t)src[3]) << 24;
|
||||
return temp;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
do_blizzard_hash,
|
||||
do_sha1_hash
|
||||
} t_hash_variant;
|
||||
|
||||
static void hash_init(t_hash * hash);
|
||||
static void do_hash(t_hash * hash, std::uint32_t * tmp);
|
||||
static void hash_set_16(std::uint32_t * dst, unsigned char const * src, unsigned int count, t_hash_variant hash_variant);
|
||||
|
||||
|
||||
static void hash_init(t_hash * hash)
|
||||
{
|
||||
(*hash)[0] = 0x67452301;
|
||||
(*hash)[1] = 0xefcdab89;
|
||||
(*hash)[2] = 0x98badcfe;
|
||||
(*hash)[3] = 0x10325476;
|
||||
(*hash)[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
|
||||
static void do_hash(t_hash * hash, std::uint32_t * tmp, t_hash_variant hash_variant)
|
||||
{
|
||||
unsigned int i;
|
||||
std::uint32_t a, b, c, d, e, g;
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
if (hash_variant == do_blizzard_hash)
|
||||
tmp[i + 16] = ROTL32(1, tmp[i] ^ tmp[i + 8] ^ tmp[i + 2] ^ tmp[i + 13]);
|
||||
else
|
||||
tmp[i + 16] = ROTL32(tmp[i] ^ tmp[i + 8] ^ tmp[i + 2] ^ tmp[i + 13], 1);
|
||||
|
||||
a = (*hash)[0];
|
||||
b = (*hash)[1];
|
||||
c = (*hash)[2];
|
||||
d = (*hash)[3];
|
||||
e = (*hash)[4];
|
||||
|
||||
for (i = 0; i < 20 * 1; i++)
|
||||
{
|
||||
g = tmp[i] + ROTL32(a, 5) + e + ((b & c) | (~b & d)) + 0x5a827999;
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROTL32(b, 30);
|
||||
b = a;
|
||||
a = g;
|
||||
}
|
||||
|
||||
for (; i < 20 * 2; i++)
|
||||
{
|
||||
g = (d ^ c ^ b) + e + ROTL32(g, 5) + tmp[i] + 0x6ed9eba1;
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROTL32(b, 30);
|
||||
b = a;
|
||||
a = g;
|
||||
}
|
||||
|
||||
for (; i < 20 * 3; i++)
|
||||
{
|
||||
g = tmp[i] + ROTL32(g, 5) + e + ((c & b) | (d & c) | (d & b)) - 0x70e44324;
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROTL32(b, 30);
|
||||
b = a;
|
||||
a = g;
|
||||
}
|
||||
|
||||
for (; i < 20 * 4; i++)
|
||||
{
|
||||
g = (d ^ c ^ b) + e + ROTL32(g, 5) + tmp[i] - 0x359d3e2a;
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROTL32(b, 30);
|
||||
b = a;
|
||||
a = g;
|
||||
}
|
||||
|
||||
(*hash)[0] += g;
|
||||
(*hash)[1] += b;
|
||||
(*hash)[2] += c;
|
||||
(*hash)[3] += d;
|
||||
(*hash)[4] += e;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill 16 elements of the array of 32 bit values with the bytes from
|
||||
* dst up to count in little endian order. Fill left over space with
|
||||
* zeros. In case of SHA1 hash variant a binary 1 is appended after
|
||||
* the actual data.
|
||||
*/
|
||||
static void hash_set_16(std::uint32_t * dst, unsigned char const * src, unsigned int count,
|
||||
t_hash_variant hash_variant)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int pos;
|
||||
|
||||
for (pos = 0, i = 0; i < 16; i++)
|
||||
{
|
||||
dst[i] = 0;
|
||||
|
||||
if (hash_variant == do_blizzard_hash) {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]);
|
||||
}
|
||||
else {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]) << 24;
|
||||
else if (pos == count)
|
||||
dst[i] |= ((std::uint32_t)0x80000000);
|
||||
}
|
||||
pos++;
|
||||
|
||||
if (hash_variant == do_blizzard_hash) {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]) << 8;
|
||||
}
|
||||
else {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]) << 16;
|
||||
else if (pos == count)
|
||||
dst[i] |= ((std::uint32_t)0x800000);
|
||||
}
|
||||
pos++;
|
||||
|
||||
if (hash_variant == do_blizzard_hash) {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]) << 16;
|
||||
}
|
||||
else {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]) << 8;
|
||||
else if (pos == count)
|
||||
dst[i] |= ((std::uint32_t)0x8000);
|
||||
}
|
||||
pos++;
|
||||
|
||||
if (hash_variant == do_blizzard_hash) {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]) << 24;
|
||||
}
|
||||
else {
|
||||
if (pos < count)
|
||||
dst[i] |= ((std::uint32_t)src[pos]);
|
||||
else if (pos == count)
|
||||
dst[i] |= ((std::uint32_t)0x80);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern int bnet_hash(t_hash * hashout, unsigned int size, void const * datain)
|
||||
{
|
||||
std::uint32_t tmp[64 + 16];
|
||||
const unsigned char* data;
|
||||
unsigned int inc;
|
||||
|
||||
if (!hashout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (size > 0 && !datain)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
hash_init(hashout);
|
||||
|
||||
data = (const unsigned char*)datain;
|
||||
while (size > 0)
|
||||
{
|
||||
if (size > 64)
|
||||
inc = 64;
|
||||
else
|
||||
inc = size;
|
||||
|
||||
hash_set_16(tmp, data, inc, do_blizzard_hash);
|
||||
do_hash(hashout, tmp, do_blizzard_hash);
|
||||
|
||||
data += inc;
|
||||
size -= inc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hash_set_length(std::uint32_t * dst, unsigned int size){
|
||||
std::uint32_t size_high = 0;
|
||||
std::uint32_t size_low = 0;
|
||||
unsigned int counter;
|
||||
for (counter = 0; counter < size; counter++){
|
||||
size_low += 8;
|
||||
if (size_low == 0)
|
||||
size_high++;
|
||||
}
|
||||
|
||||
dst[14] |= ((size_high >> 24) & 0xff) << 24;
|
||||
dst[14] |= ((size_high >> 16) & 0xff) << 16;
|
||||
dst[14] |= ((size_high >> 8) & 0xff) << 8;
|
||||
dst[14] |= ((size_high)& 0xff);
|
||||
|
||||
dst[15] |= ((size_low >> 24) & 0xff) << 24;
|
||||
dst[15] |= ((size_low >> 16) & 0xff) << 16;
|
||||
dst[15] |= ((size_low >> 8) & 0xff) << 8;
|
||||
dst[15] |= ((size_low)& 0xff);
|
||||
}
|
||||
|
||||
extern int sha1_hash(t_hash * hashout, unsigned int size, void const * datain)
|
||||
{
|
||||
std::uint32_t tmp[64 + 16];
|
||||
unsigned char const * data;
|
||||
unsigned int inc;
|
||||
unsigned int orgSize;
|
||||
|
||||
if (!hashout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (size > 0 && !datain)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
hash_init(hashout);
|
||||
orgSize = size;
|
||||
|
||||
data = (const unsigned char*)datain;
|
||||
while (size > 0)
|
||||
{
|
||||
if (size >= 64)
|
||||
inc = 64;
|
||||
else
|
||||
inc = size;
|
||||
|
||||
if (size >= 64)
|
||||
{
|
||||
hash_set_16(tmp, data, inc, do_sha1_hash);
|
||||
do_hash(hashout, tmp, do_sha1_hash);
|
||||
}
|
||||
else if (size > 55){
|
||||
|
||||
hash_set_16(tmp, data, inc, do_sha1_hash);
|
||||
do_hash(hashout, tmp, do_sha1_hash);
|
||||
|
||||
// now use blizz variant as we only wanna fill in zeros
|
||||
hash_set_16(tmp, data, 0, do_blizzard_hash);
|
||||
hash_set_length(tmp, orgSize);
|
||||
do_hash(hashout, tmp, do_sha1_hash);
|
||||
}
|
||||
else{
|
||||
hash_set_16(tmp, data, inc, do_sha1_hash);
|
||||
hash_set_length(tmp, orgSize);
|
||||
do_hash(hashout, tmp, do_sha1_hash);
|
||||
}
|
||||
|
||||
data += inc;
|
||||
size -= inc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int little_endian_sha1_hash(t_hash * hashout, unsigned int size, void const * datain)
|
||||
{
|
||||
bn_int value;
|
||||
unsigned int i;
|
||||
sha1_hash(hashout, size, datain);
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
bn_int_nset(&value, (*hashout)[i]);
|
||||
(*hashout)[i] = bn_int_get(value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int hash_eq(t_hash const h1, t_hash const h2)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!h1 || !h2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (h1[i] != h2[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
extern char const * hash_get_str(t_hash const hash)
|
||||
{
|
||||
static char temp[8 * 5 + 1]; /* each of 5 ints to 8 chars + null */
|
||||
unsigned int i;
|
||||
|
||||
if (!hash)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
std::sprintf(&temp[i * 8], "%08x", hash[i]);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
extern char const * little_endian_hash_get_str(t_hash const hash)
|
||||
{
|
||||
bn_int value;
|
||||
t_hash be_hash;
|
||||
unsigned int i;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
bn_int_nset(&value, hash[i]);
|
||||
be_hash[i] = bn_int_get(value);
|
||||
}
|
||||
return hash_get_str(be_hash);
|
||||
}
|
||||
|
||||
|
||||
extern int hash_set_str(t_hash * hash, char const * str)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!hash)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (!*hash)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (!str)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (std::strlen(str) != 5 * 8)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
if (std::sscanf(&str[i * 8], "%8x", &(*hash)[i]) != 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bnhash_to_hash(bn_int const * bnhash, t_hash * hash)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!bnhash)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!hash)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
(*hash)[i] = bn_int_get(bnhash[i]);
|
||||
}
|
||||
|
||||
|
||||
void hash_to_bnhash(t_hash const * hash, bn_int * bnhash)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!bnhash)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!hash)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
bn_int_set(&bnhash[i], (*hash)[i]);
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,7 @@
|
|||
// Includes
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "online_service.h"
|
||||
#include "stratagus.h"
|
||||
|
||||
#include "actions.h"
|
||||
|
@ -418,6 +419,10 @@ void GameMainLoop()
|
|||
//
|
||||
// Game over
|
||||
//
|
||||
if (ThisPlayer && IsNetworkGame()) {
|
||||
OnlineContextHandler->reportGameResult();
|
||||
}
|
||||
|
||||
if (GameResult == GameExit) {
|
||||
Exit(0);
|
||||
return;
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
$#include "master.h"
|
||||
|
||||
struct CClientLog
|
||||
{
|
||||
std::string entry;
|
||||
};
|
||||
|
||||
class CMetaClient
|
||||
{
|
||||
public:
|
||||
CMetaClient();
|
||||
void SetMetaServer(const std::string host, const int port);
|
||||
int Init();
|
||||
void Close();
|
||||
int Send(const std::string cmd);
|
||||
int Recv();
|
||||
int GetLastRecvState() { return lastRecvState; }
|
||||
int GetLogSize() { return events.size(); }
|
||||
CClientLog* GetLastMessage() { return events.back(); }
|
||||
int CreateGame(std::string desc, std::string map, std::string players);
|
||||
};
|
||||
|
||||
CMetaClient MetaClient;
|
|
@ -73,7 +73,6 @@ $pfile "editor.pkg"
|
|||
$pfile "font.pkg"
|
||||
$pfile "game.pkg"
|
||||
$pfile "map.pkg"
|
||||
$pfile "master.pkg"
|
||||
$pfile "minimap.pkg"
|
||||
$pfile "network.pkg"
|
||||
$pfile "particle.pkg"
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "online_service.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <signal.h>
|
||||
|
@ -676,6 +677,10 @@ void WaitEventsOneFrame()
|
|||
GetCallbacks()->NetworkEvent();
|
||||
}
|
||||
}
|
||||
|
||||
// Online session
|
||||
OnlineContextHandler->doOneStep();
|
||||
|
||||
// No more input and time for frame over: return
|
||||
if (!i && s <= 0 && interrupts) {
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue