Skip to content

Commit

Permalink
net: Add initial relay support
Browse files Browse the repository at this point in the history
  • Loading branch information
IonAgorria committed Mar 20, 2024
1 parent 2503702 commit ed9ae9f
Show file tree
Hide file tree
Showing 60 changed files with 3,793 additions and 3,412 deletions.
4 changes: 0 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,14 @@ OPTION(OPTION_FINAL_VERSION "Generate Final version" ON)
OPTION(OPTION_STATIC_BUILD "Generate static build" OFF)
OPTION(OPTION_STATIC_LIB_STD "Statically link to libstd++" ON)
OPTION(OPTION_CHECK_SCRIPTS "Check game scripts with XPrm" OFF)
OPTION(OPTION_PROCESS_SCRIPTS "Re-Process game scripts with XPrm" OFF)
OPTION(OPTION_DISABLE_STACKTRACE "Disable stacktrace support" OFF)
OPTION(OPTION_LINKER "Use specified linker instead of default" "")
OPTION(OPTION_DEBUG_ASSERT "Enable debug assertions" OFF)
OPTION(OPTION_GPERFTOOLS "Link executable with gperftools for debugging" OFF)
OPTION(OPTION_D3D9 "Enable D3D9 renderer using dxvk in *nix or DirectX in Windows" ON)
OPTION(OPTION_LINK_LIBS "Link executables with provided libraries, placed before the rest" "")
OPTION(OPTION_LINK_LIBS_POST "Link executables with provided libraries, placed after the rest" "")
OPTION(OPTION_DXVK_1 "Use old DXVK-native (DXVK 1.x) instead of DXVK 2.x" OFF)
OPTION(OPTION_DXVK_SOURCE_DIR "Path for predownloaded DXVK source code")
OPTION(OPTION_SOKOL "Enable Sokol GFX based renderer" ON)
OPTION(OPTION_PROCESS_SHADERS "Re-Process game shaders" OFF)
OPTION(OPTION_FFMPEG_MOVIES "Use FFMPEG to decode ingame movies" ON)
OPTION(OPTION_ASAN "Enable AddressSanitizer" OFF)
OPTION(OPTION_O0 "Disable optimizations" OFF)
Expand Down
5 changes: 4 additions & 1 deletion Source/Game/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@

OPTION(OPTION_PROCESS_SCRIPTS "Re-Process game scripts with XPrm" OFF)

target_sources(perimeter PRIVATE
CameraManager.cpp
MonkManager.cpp
Expand Down Expand Up @@ -143,7 +146,7 @@ SET(perimeter_LINK_LIBS
IF(PERIMETER_WINDOWS)
SET(perimeter_LINK_LIBS ${perimeter_LINK_LIBS} ${SDL2MAIN_LIBRARY})
ENDIF()

message(${perimeter_LINK_LIBS})
target_link_libraries(perimeter PRIVATE ${perimeter_LINK_LIBS})

#Install rules
Expand Down
3 changes: 0 additions & 3 deletions Source/Game/GameContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,8 @@ int firstMissionNumber = 0;

static std::map<std::string, ModMetadata> gameMods;

///The identified content at the root of game content, this only can be one thing
GAME_CONTENT terGameContentBase = CONTENT_NONE;
///All available contents in this installation (base + addons)
GAME_CONTENT terGameContentAvailable = CONTENT_NONE;
///Current selected content, can be several or only one in available content (when user chooses one)
GAME_CONTENT terGameContentSelect = CONTENT_NONE;

std::map<std::string, ModMetadata>& getGameMods() {
Expand Down
3 changes: 3 additions & 0 deletions Source/Game/GameContent.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#ifndef PERIMETER_GAMECONTENT_H
#define PERIMETER_GAMECONTENT_H

///The identified content at the root of game content, this only can be one thing
extern GAME_CONTENT terGameContentBase;
///All available contents in this installation (base + addons)
extern GAME_CONTENT terGameContentAvailable;
///Current selected content, can be several or only one in available content (when user chooses one)
extern GAME_CONTENT terGameContentSelect;

/**
Expand Down
3 changes: 2 additions & 1 deletion Source/Game/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,8 @@ void show_help() {
"\n"
"Multiplayer:\n"
" server=IP:PORT - Opens game in server mode and binds to address\n"
" connect=IP:PORT - Connects to provided server address\n"
" connect=IP:PORT - Connects as client to provided server address\n"
" connect_room=ROOMID - Connects as client to provided room id\n"
" password=Password - Password to use as server or connecting to server\n"
" name=Name - Player name to use as server or connecting to server\n"
" save=savegame - Multiplayer save name to use to resume as server\n"
Expand Down
718 changes: 477 additions & 241 deletions Source/Game/Scripts/InterfaceScriptExport.cppi

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions Source/Game/Texts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,13 @@ void qdTextDB::load_supplementary_texts(const std::string& locale) {
"Interface.Menu.ComboItems.Classic=Классический",
"Interface.Menu.Multiplayer.StartNewGame=Начать новую игру",
"Interface.Menu.Multiplayer.Server=сервер",
"Interface.Tips.Multiplayer.HasPassword=Имеет пароль",
"Interface.Tips.Multiplayer.GameStarted=Игра уже началась",
"Interface.Tips.Multiplayer.Game=Игра",
"Interface.Tips.Multiplayer.Map=Карта",
"Interface.Tips.Multiplayer.CurrentPlayers=Текущие игроки",
"Interface.Tips.Multiplayer.MaxPlayers=Макс игроков",
"Interface.Tips.Multiplayer.Ping=Пинг",
"Interface.Menu.Messages.WrongIPPort=Этот IP-адрес недоступен",
"Interface.Menu.Messages.Multiplayer.IncorrectContent=Сервер содержит другие игровые ресурсы",
"Interface.Menu.Messages.Multiplayer.IncorrectArch=Сервер имеет другую битность или архитектуру ЦПУ, другой тип билда (Debug/Release), операционную систему или использован другой компилятор (MSVC/Clang/GCC), пожалуйста, убедитесь, что они совпадают",
Expand Down Expand Up @@ -887,6 +894,13 @@ void qdTextDB::load_supplementary_texts(const std::string& locale) {
"Interface.Menu.ComboItems.Classic=Classic",
"Interface.Menu.Multiplayer.StartNewGame=Start a new game",
"Interface.Menu.Multiplayer.Server=Server",
"Interface.Tips.Multiplayer.HasPassword=Has password",
"Interface.Tips.Multiplayer.GameStarted=Game has already started",
"Interface.Tips.Multiplayer.Game=Game",
"Interface.Tips.Multiplayer.Map=Map",
"Interface.Tips.Multiplayer.CurrentPlayers=Current players",
"Interface.Tips.Multiplayer.MaxPlayers=Max players",
"Interface.Tips.Multiplayer.Ping=Ping",
"Interface.Menu.Messages.WrongIPPort=IP port is wrong",
"Interface.Menu.Messages.Multiplayer.IncorrectContent=Server has different game content",
"Interface.Menu.Messages.Multiplayer.IncorrectArch=Server has different bits or CPU architecture, different build type (Debug/Release), Operating System or used a different compiler (MSVC/Clang/GCC), please ensure they match",
Expand Down
1 change: 1 addition & 0 deletions Source/Network/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_library(Network STATIC
P2P_interfaceAnyTh.cpp
NetConnection.cpp
NetConnectionHandler.cpp
NetRelay.cpp
)

target_include_directories(Network PRIVATE
Expand Down
4 changes: 1 addition & 3 deletions Source/Network/CommonEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ enum terEventID
NETCOM_ID_NEXT_QUANT,

////---
NETCOMC_ID_JOIN_REQUEST,
NETCOM_4C_ID_JOIN_RESPONSE,

NETCOM_4H_ID_REJOIN_REQUEST,
NETCOM_4C_ID_REJOIN_RESPONCE,
Expand Down Expand Up @@ -739,7 +737,7 @@ struct netCommand4C_ReJoinResponse : netCommandGeneral
{
NETID playerNETID_;
NETID groupNETID_;
netCommand4C_JoinResponse(NETID playerNETID, NETID groupNETID) : netCommandGeneral(NETCOM_4C_ID_REJOIN_RESPONSE) {
netCommand4C_ReJoinResponse(NETID playerNETID, NETID groupNETID) : netCommandGeneral(NETCOM_4C_ID_REJOIN_RESPONSE) {
playerNETID_=playerNETID;
groupNETID_=groupNETID;
}
Expand Down
43 changes: 30 additions & 13 deletions Source/Network/HyperSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,36 +222,53 @@ void terHyperSpace::deserializeGameCommands(XBuffer& in, size_t len) {
xassert(len >= sizeof(endQuant_inReplayListGameCommands));
len -= in.read(&endQuant_inReplayListGameCommands, sizeof(endQuant_inReplayListGameCommands));

InOutNetComBuffer in_buffer(len, true); //проверить необходимость автоувелечения!
in_buffer.putBufferPacket(in.address()+in.tell(), len);
InOutNetComBuffer in_buffer(len, false);
char* data_ptr = in.address() + in.tell();
uint32_t packet_id = *(reinterpret_cast<uint32_t*>(data_ptr));
if (packet_id != NETCOM_BUFFER_PACKET_ID) {
in_buffer.automatic_realloc = true;
event_size_t event_len = 0;
size_t event_start = 0;
while (in.tell() + sizeof(event_len) < in.length()) {
event_start = in.tell();
in.read(&event_len, sizeof(event_len));
if (event_len == 0 || (in.tell() + event_len) > in.length()) {
break;
}
in_buffer.write(&NETCOM_BUFFER_PACKET_ID, sizeof(NETCOM_BUFFER_PACKET_ID));
in_buffer.write(&event_len, sizeof(event_len));
in_buffer.write(data_ptr + event_start, event_len);
in.set(event_start + event_len);
}
in_buffer.filled_size = in_buffer.tell();
in_buffer.set(0);
} else {
in_buffer.putBufferPacket(data_ptr, len);
}

while(in_buffer.currentNetCommandID()!=NETCOM_ID_NONE) {
while (in_buffer.nextNetCommand() != NETCOM_ID_NONE) {
terEventID event = (terEventID)in_buffer.currentNetCommandID();
switch(event){
case NETCOM_4G_ID_UNIT_COMMAND:
{
case NETCOM_4G_ID_UNIT_COMMAND: {
netCommand4G_UnitCommand* pnc= new netCommand4G_UnitCommand(in_buffer);
replayListGameCommands.push_back(pnc);
}
break;
case NETCOM_4G_ID_REGION:
{
}
case NETCOM_4G_ID_REGION: {
netCommand4G_Region* pnc= new netCommand4G_Region(in_buffer);
replayListGameCommands.push_back(pnc);
}
break;
case NETCOM_4G_ID_FORCED_DEFEAT:
{
}
case NETCOM_4G_ID_FORCED_DEFEAT: {
netCommand4G_ForcedDefeat* pnc=new netCommand4G_ForcedDefeat(in_buffer);
replayListGameCommands.push_back(pnc);
break;
}

default:
xassert(0&&"Incorrect commanf in playReel file!");
xassert(0&&"Incorrect command in playReel file!");
break;
}
in_buffer.nextNetCommand();
}
}

Expand Down
48 changes: 31 additions & 17 deletions Source/Network/NetComEventBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,11 @@ void InOutNetComBuffer::putNetCommand(const netCommandGeneral* event)
{
clearBufferOfTheProcessedCommands();
set(filled_size);
unsigned int pointer_to_size_of_event;
//unsigned int size_of_event;
pointer_to_size_of_event = offset;
size_of_event=0;
event_ID=event->EventID;
write(&NETCOM_BUFFER_PACKET_ID, sizeof(NETCOM_BUFFER_PACKET_ID));
unsigned int pointer_to_size_of_event = offset;
event_size_t size_of_event = 0;
write(&size_of_event, sizeof(size_of_event));
event_ID=event->EventID;
write(&event_ID, sizeof(event_ID));

event->Write(*this);
Expand All @@ -71,12 +70,10 @@ void InOutNetComBuffer::putNetCommand(const netCommandGeneral* event)
set(0);
//для нормального next event
event_ID = NETCOM_ID_NONE;
size_of_event=0;
}

//in
void InOutNetComBuffer::clearBufferOfTheProcessedCommands(void)
{
void InOutNetComBuffer::clearBufferOfTheProcessedCommands() {
if(next_event_pointer){
if(filled_size != next_event_pointer)
memmove(address(),address() + next_event_pointer, filled_size - next_event_pointer);
Expand All @@ -87,16 +84,28 @@ void InOutNetComBuffer::clearBufferOfTheProcessedCommands(void)

bool InOutNetComBuffer::putBufferPacket(char* buf, unsigned int size)
{
if (size < SIZE_HEAD_PACKET) {
fprintf(stderr, "Buffer packet is too small\n");
xassert(0);
return false;
}
uint32_t packet_id = *(reinterpret_cast<uint32_t*>(buf));
if (packet_id != NETCOM_BUFFER_PACKET_ID) {
fprintf(stderr, "Buffer packet is not a netcom buffer\n");
xassert(0);
return false;
}
clearBufferOfTheProcessedCommands();
if(length()-filled_size < size) {
xassert(0 && "Net input buffer is small.");
return 0;
fprintf(stderr, "Net input buffer is small\n");
xassert(0);
return false;
}
memcpy(address() + filled_size, buf, size);
byte_receive+=size;
filled_size +=size;
//nextNetCommand();
return 1;
return true;
}

int InOutNetComBuffer::currentNetCommandID()
Expand All @@ -110,8 +119,8 @@ int InOutNetComBuffer::currentNetCommandID()

terEventID InOutNetComBuffer::nextNetCommand()
{
if(event_ID != NETCOM_ID_NONE){
if(next_event_pointer /*+ sizeof(size_of_event)*/ > filled_size){
if (event_ID != NETCOM_ID_NONE) {
if(next_event_pointer > filled_size){
xassert(0&&"Incomplete packet ?!");
init();
reset();
Expand All @@ -130,9 +139,15 @@ terEventID InOutNetComBuffer::nextNetCommand()

event_ID = NETCOM_ID_NONE;

if(filled_size-tell() > (sizeof(size_of_event) + sizeof(event_ID)) ) {
read(&size_of_event, sizeof(size_of_event)); //get_short();
unsigned int new_pointer = next_event_pointer + size_of_event + sizeof(size_of_event);
if (filled_size-tell() > SIZE_HEAD_PACKET) {
uint32_t packet_id = 0;
read(&packet_id, sizeof(NETCOM_BUFFER_PACKET_ID));
if (packet_id != NETCOM_BUFFER_PACKET_ID) {
ErrH.Abort("Couldn't match packet header ID, wrong data in input buffer?");
}
event_size_t size_of_event = 0;
read(&size_of_event, sizeof(size_of_event));
unsigned int new_pointer = next_event_pointer + size_of_event + sizeof(size_of_event) + sizeof(packet_id);
if(new_pointer > filled_size){
xassert(0&&"Incomplete packet ?!");
set(next_event_pointer);
Expand All @@ -156,7 +171,6 @@ void InOutNetComBuffer::ignoreNetCommand()

void InOutNetComBuffer::backNetCommand()
{
const unsigned int SIZE_HEAD_PACKET=sizeof(event_ID)+sizeof(size_of_event);
if(offset>=SIZE_HEAD_PACKET){
event_ID = NETCOM_ID_NONE;
offset-=SIZE_HEAD_PACKET;
Expand Down
3 changes: 2 additions & 1 deletion Source/Network/NetComEventBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "CommonEvents.h"

typedef uint32_t event_size_t;
const uint32_t NETCOM_BUFFER_PACKET_ID = 0xB1FFE90D;
const unsigned int SIZE_HEAD_PACKET = sizeof(NETCOM_BUFFER_PACKET_ID) + sizeof(event_size_t) + sizeof(terEventID);

class PNetCenter;
class InOutNetComBuffer : public XBuffer
Expand All @@ -14,7 +16,6 @@ class InOutNetComBuffer : public XBuffer
size_t byte_sending;//out

terEventID event_ID;//in
event_size_t size_of_event;//in
size_t next_event_pointer;//in
size_t filled_size;//in
InOutNetComBuffer(unsigned int size, bool autoRealloc);
Expand Down
Loading

0 comments on commit ed9ae9f

Please sign in to comment.