tighten down calls for game join/part and start/stop

This commit is contained in:
Tim Felgentreff 2020-08-13 15:10:35 +02:00
parent 61d4818a68
commit fd8c5eb329
8 changed files with 183 additions and 18 deletions

View file

@ -362,7 +362,6 @@ source_group(win32 FILES ${win32_SRCS})
set(tolua_FILES
src/tolua/ai.pkg
src/tolua/editor.pkg
src/tolua/online_service.pkg
src/tolua/font.pkg
src/tolua/game.pkg
src/tolua/map.pkg

View file

@ -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();
}

View file

@ -100,6 +100,8 @@ extern int NetLocalPlayerNumber; /// Player number of local client
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
----------------------------------------------------------------------------*/

View file

@ -1,23 +1,31 @@
#ifndef __ONLINE_SERVICE_H__
#define __ONLINE_SERVICE_H__
#include <string>
class OnlineContext {
public:
// called in the sdl event loop
virtual void doOneStep();
virtual void goOnline();
// called when joining a network game
virtual void joinGame(std::string hostPlayerName, std::string pw);
virtual void joinGame(std:string name, std::string pw);
// called when leaving a network game
virtual void leaveGame();
// TODO: allow passing all the other options, like 1 peon only, resource amount, game type, ...
virtual void advertiseGame(std::string name, std::string pw, std::string creatorName, std::string mapName,
int mapX, int mapY, int maxPlayers, int playersInGame);
// called when advertised game is starting (just reports the game as in-progress)
virtual void startAdvertising(bool isStarted = false);
virtual void stopAdvertisingGame();
// called when advertised game is left by the server
virtual void stopAdvertising();
// called when network game ends
virtual void reportGameResult();
};
extern OnlineContext *OnlineContextHandler;
extern void OnlineServiceCclRegister();
#endif

View file

@ -33,6 +33,7 @@
// Includes
//----------------------------------------------------------------------------
#include "online_service.h"
#include "stratagus.h"
#include "netconnect.h"
@ -86,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
@ -781,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) {
@ -1705,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) {

View file

@ -1,5 +1,5 @@
#include "online_service.h"
#include "master.h"
#include "results.h"
#include <arpa/inet.h>
#include <clocale>
@ -7,6 +7,7 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ios>
#include <iostream>
#include <map>
#include <ostream>
@ -25,6 +26,13 @@
#include <netinet/in.h>
#endif
#include "stratagus.h"
#include "lua.h"
#include "map.h"
#include "netconnect.h"
#include "script.h"
#include "settings.h"
#include "tileset.h"
#include "cursor.h"
#include "font.h"
#include "input.h"
@ -42,7 +50,6 @@
#include "./xsha1.h"
class BNCSInputStream {
public:
BNCSInputStream(CTCPSocket *socket) {
@ -677,16 +684,134 @@ public:
msg.flush(getTCPSocket());
}
void joinGame(std::string name, std::string pw) {
virtual void joinGame(std::string username, std::string pw) {
if (!isConnected()) {
return;
}
// C>S 0x22 SID_NOTIFYJOIN
BNCSOutputStream msg(0x09);
msg.serializeC32("W2BN");
msg.serialize32(0x4f);
msg.serialize(name.c_str());
msg.serialize(gameNameFromUsername(getUsername()).c_str());
msg.serialize(pw.c_str());
msg.flush(getTCPSocket());
}
virtual void leaveGame() {
// TODO: ?
}
virtual void startAdvertising(bool isStarted = false) {
if (!isConnected()) {
return;
}
BNCSOutputStream msg(0x1c);
int maxSlots = 0;
for (int i = 0; i < PlayerMax; i++) {
if (ServerSetupState.CompOpt[i] == 0) { // available
maxSlots++;
}
}
int joinedPlayers = 0;
for (int i = 1; i < PlayerMax; i++) { // skip server host
if (Hosts[i].PlyNr) {
joinedPlayers++;
}
}
uint32_t state = 0x10; // disconnect always counts as loss
if (joinedPlayers) {
state |= 0x04; // has players other than creator
}
if (joinedPlayers + 1 == maxSlots) {
state |= 0x02; // game is full
}
if (isStarted) {
state |= 0x08; // game in progress
}
msg.serialize32(state);
msg.serialize32(0x00); // uptime
msg.serialize16(0x0a); // game type - map settings
msg.serialize16(0x01); // sub game type
msg.serialize32(0xff); // provider version constant
msg.serialize32(0x00); // not ladder
msg.serialize((gameNameFromUsername(getUsername())).c_str()); // game name
msg.serialize(""); // password. TODO: add support
std::stringstream statstring;
statstring << ","; // this game is not saved. TODO: add support
int w = Map.Info.MapWidth;
int h = Map.Info.MapWidth;
if (w == 128 && h == 128) {
statstring << ",";
} else {
statstring << std::dec << w / 32 << h / 32 << ",";
}
if (maxSlots == 8) {
statstring << ",";
} else {
statstring << std::dec << maxSlots + 10 << ",";
}
statstring << "0x04,"; // speed - normal (can be changed in-game anyway)
statstring << "0x00,"; // not an approved game
statstring << "0x0a,"; // game type uses map settings
statstring << "0x01,"; // game settings parameter - none
statstring << std::hex << FileChecksums << ","; // cd key checksum - we use lua files checksum
uint32_t game_settings = 0;
if (GameSettings.NumUnits == 1) {
game_settings |= 0x200;
}
if (NoRandomPlacementMultiplayer == 1) {
game_settings |= 0x400;
}
switch (GameSettings.Resources) {
case -1:
break;
case 1:
game_settings |= 0x1000;
break;
case 2:
game_settings |= 0x2000;
break;
case 3:
game_settings |= 0x3000;
break;
default:
game_settings |= 0x20000;
break;
}
if (Map.Tileset->Name == "Forest") {
game_settings |= 0x4000;
} else if (Map.Tileset->Name == "Winter") {
game_settings |= 0x8000;
} else if (Map.Tileset->Name == "Wasteland") {
game_settings |= 0xC000;
} else if (Map.Tileset->Name == "Orc Swamp") {
game_settings |= 0x1C000;
}
statstring << std::hex << game_settings << ",";
statstring << getUsername();
statstring.put(0x0d);
statstring << Map.Info.Filename;
statstring.put(0x0d);
msg.serialize(statstring.str().c_str());
msg.flush(getTCPSocket());
}
virtual void stopAdvertising() {
if (!isConnected()) {
return;
}
BNCSOutputStream msg(0x02);
msg.flush(getTCPSocket());
}
virtual void reportGameResult() {
GameResult
}
// UI information
void setCurrentChannel(std::string name) {
this->currentChannel = name;
@ -795,6 +920,10 @@ public:
uint32_t serverToken;
private:
std::string gameNameFromUsername(std::string username) {
return username + "'s game";
}
NetworkState *state;
CHost *host;
CUDPSocket *udpSocket;
@ -1507,9 +1636,9 @@ class ConnectState : public NetworkState {
// Connect
std::string localHost = CNetworkParameter::Instance.localHost;
if (!localHost.compare("127.0.0.1")) {
if (!localHost.compare("127.0.0.1")) {
localHost = "0.0.0.0";
}
}
if (!ctx->getTCPSocket()->Open(CHost(localHost.c_str(), CNetworkParameter::Instance.localPort))) {
ctx->setState(new DisconnectedState("TCP open failed"));
return;
@ -1640,7 +1769,7 @@ class PasswordInputListener : public gcn::ActionListener {
}
};
void GoOnline() {
static int CclGoOnline(lua_State* l) {
std::string nc, rc;
GetDefaultTextColors(nc, rc);
@ -1801,4 +1930,20 @@ void GoOnline() {
delete loginWindowContainer;
delete username;
delete password;
return 0;
}
static int CclStopAdvertisingOnlineGame(lua_State* l) {
return 0;
}
static int CclStartAdvertisingOnlineGame(lua_State* l) {
return 0;
}
void OnlineServiceCclRegister() {
lua_register(Lua, "StartAdvertisingOnlineGame", CclStartAdvertisingOnlineGame);
lua_register(Lua, "StopAdvertisingOnlineGame", CclStopAdvertisingOnlineGame);
lua_register(Lua, "GoOnline", CclGoOnline);
}

View file

@ -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;

View file

@ -1,3 +0,0 @@
$#include "online_service.h"
void GoOnline();