summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 62ceb85)
raw | patch | inline | side by side (parent: 62ceb85)
author | Dmitry D. Chernov <blackdoomer@yandex.ru> | |
Sat, 15 Jul 2023 17:19:40 +0000 (03:19 +1000) | ||
committer | Dmitry D. Chernov <blackdoomer@yandex.ru> | |
Sat, 15 Jul 2023 17:19:40 +0000 (03:19 +1000) |
maybe some other time, I hope
src/game/g_net.pas | patch | blob | history | |
src/game/g_netmsg.pas | patch | blob | history |
diff --git a/src/game/g_net.pas b/src/game/g_net.pas
index 6d1be31fa920990a39f9ff7f95ce0ab66a437402..d97d4bd07675033281e6a61b888d390eb52a40ab 100644 (file)
--- a/src/game/g_net.pas
+++ b/src/game/g_net.pas
const
NET_PROTOCOL_VER = 188;
-
NET_MAXCLIENTS = 24;
- NET_CHANS = 12;
-
- NET_CHAN_SERVICE = 0;
- NET_CHAN_IMPORTANT = 1;
- NET_CHAN_GAME = 2;
- NET_CHAN_PLAYER = 3;
- NET_CHAN_PLAYERPOS = 4;
- NET_CHAN_MONSTER = 5;
- NET_CHAN_MONSTERPOS = 6;
- NET_CHAN_LARGEDATA = 7;
- NET_CHAN_CHAT = 8;
- NET_CHAN_DOWNLOAD = 9;
- NET_CHAN_SHOTS = 10;
- NET_CHAN_DOWNLOAD_EX = 11;
+
+ // NOTE: We use different channels for unreliable and reliable packets because ENet seems to
+ // discard preceeding RELIABLE packets if a later UNRELIABLE (but not UNSEQUENCED) packet sent
+ // on the same channel has arrived earlier, which is useful for occasional full-state updates.
+ // However, we use a separate download channel to avoid being delayed by other reliable packets.
+ NET_CHAN_UNRELIABLE = 2;
+ NET_CHAN_RELIABLE = 1;
+ NET_CHAN_DOWNLOAD = 11;
+ NET_CHANNELS = 12; // TODO: Reduce to 3 and re-enumerate channels. Requires protocol increment.
NET_NONE = 0;
NET_SERVER = 1;
function g_Net_Host(IPAddr: LongWord; Port: enet_uint16; MaxClients: Cardinal = 16): Boolean;
procedure g_Net_Host_Die();
-procedure g_Net_Host_Send(ID: Integer; Reliable: Boolean; Chan: Byte = NET_CHAN_GAME);
+procedure g_Net_Host_Send(ID: Integer; Reliable: Boolean);
procedure g_Net_Host_Update();
procedure g_Net_Host_Kick(ID: Integer; Reason: enet_uint32);
function g_Net_Connect(IP: string; Port: enet_uint16): Boolean;
procedure g_Net_Disconnect(Forced: Boolean = False);
-procedure g_Net_Client_Send(Reliable: Boolean; Chan: Byte = NET_CHAN_GAME);
+procedure g_Net_Client_Send(Reliable: Boolean);
procedure g_Net_Client_Update();
function g_Net_Client_ByName(Name: string): pTNetClient;
function g_Net_Client_ByPlayer(PID: Word): pTNetClient;
function g_Net_ClientName_ByID(ID: Integer): string;
-procedure g_Net_SendData(Data: AByte; peer: pENetPeer; Reliable: Boolean; Chan: Byte = NET_CHAN_DOWNLOAD);
-//function g_Net_Wait_Event(msgId: Word): TMemoryStream;
-//function g_Net_Wait_FileInfo (var tf: TNetFileTransfer; asMap: Boolean; out resList: TStringList): Integer;
-
function IpToStr(IP: LongWord): string;
function StrToIp(IPstr: string; var IP: LongWord): Boolean;
if (m.CurSize < 1) then exit;
pkt := enet_packet_create(m.Data, m.CurSize, ENET_PACKET_FLAG_RELIABLE);
if not Assigned(pkt) then begin killClientByFT(nc); exit; end;
- if (enet_peer_send(nc.Peer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then begin killClientByFT(nc); exit; end;
+ if (enet_peer_send(nc.Peer, NET_CHAN_DOWNLOAD, pkt) <> 0) then begin killClientByFT(nc); exit; end;
result := true;
end;
if (m.CurSize < 1) then exit;
pkt := enet_packet_create(m.Data, m.CurSize, ENET_PACKET_FLAG_RELIABLE);
if not Assigned(pkt) then exit;
- if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD_EX, pkt) <> 0) then exit;
+ if (enet_peer_send(NetPeer, NET_CHAN_DOWNLOAD, pkt) <> 0) then exit;
result := true;
end;
ENET_EVENT_TYPE_RECEIVE:
begin
freePacket := true;
- if (ev.channelID <> NET_CHAN_DOWNLOAD_EX) then
+ if (ev.channelID <> NET_CHAN_DOWNLOAD) then
begin
//e_LogWritefln('g_Net_Wait_MapInfo: skip message from non-transfer channel', []);
freePacket := false;
rc := msg.ReadLongInt();
if (rc < 0) or (rc > 1024) then
begin
- e_LogWritefln('g_Net_Wait_Event: invalid number of map external resources (%d)', [rc]);
+ e_LogWritefln('g_Net_Wait_MapInfo: invalid number of map external resources (%d)', [rc]);
Result := -1;
exit;
end;
end
else
begin
- e_LogWritefln('g_Net_Wait_Event: invalid server packet type', []);
+ e_LogWritefln('g_Net_Wait_MapInfo: invalid server packet type', []);
Result := -1;
exit;
end;
ENET_EVENT_TYPE_RECEIVE:
begin
freePacket := true;
- if (ev.channelID <> NET_CHAN_DOWNLOAD_EX) then
+ if (ev.channelID <> NET_CHAN_DOWNLOAD) then
begin
- //e_LogWriteln('g_Net_Wait_Event: skip message from non-transfer channel');
+ //e_LogWriteln('g_Net_RequestResFileInfo: skip message from non-transfer channel');
freePacket := false;
g_Net_Client_HandlePacket(ev.packet, g_Net_ClientLightMsgHandler);
if (g_Res_received_map_start < 0) then begin result := -666; exit; end;
ett := getNewTimeoutEnd();
if (ev.packet.dataLength < 1) then
begin
- e_LogWriteln('g_Net_Wait_Event: invalid server packet (no data)');
+ e_LogWriteln('g_Net_RequestResFileInfo: invalid server packet (no data)');
Result := -1;
exit;
end;
ENET_EVENT_TYPE_RECEIVE:
begin
freePacket := true;
- if (ev.channelID <> NET_CHAN_DOWNLOAD_EX) then
+ if (ev.channelID <> NET_CHAN_DOWNLOAD) then
begin
- //e_LogWritefln('g_Net_Wait_Event: skip message from non-transfer channel', []);
+ //e_LogWritefln('g_Net_ReceiveResourceFile: skip message from non-transfer channel', []);
freePacket := false;
g_Net_Client_HandlePacket(ev.packet, g_Net_ClientLightMsgHandler);
if (g_Res_received_map_start < 0) then begin result := -666; exit; end;
I: Integer;
begin
F := 0;
- Chan := NET_CHAN_GAME;
+ Chan := NET_CHAN_UNRELIABLE;
if NetMode = NET_SERVER then
for T := NET_UNRELIABLE to NET_RELIABLE do
// next and last iteration is always RELIABLE
F := LongWord(ENET_PACKET_FLAG_RELIABLE);
- Chan := NET_CHAN_IMPORTANT;
+ Chan := NET_CHAN_RELIABLE;
end
else if NetMode = NET_CLIENT then
for T := NET_UNRELIABLE to NET_RELIABLE do
end;
// next and last iteration is always RELIABLE
F := LongWord(ENET_PACKET_FLAG_RELIABLE);
- Chan := NET_CHAN_IMPORTANT;
+ Chan := NET_CHAN_RELIABLE;
end;
end;
NetAddr.host := IPAddr;
NetAddr.port := Port;
- NetHost := enet_host_create(@NetAddr, NET_MAXCLIENTS, NET_CHANS, 0, 0);
+ NetHost := enet_host_create(@NetAddr, NET_MAXCLIENTS, NET_CHANNELS, 0, 0);
if (NetHost = nil) then
begin
end;
-procedure g_Net_Host_Send(ID: Integer; Reliable: Boolean; Chan: Byte = NET_CHAN_GAME);
+procedure g_Net_Host_Send(ID: Integer; Reliable: Boolean);
var
T: Integer;
begin
- if (Reliable) then
- T := NET_RELIABLE
- else
- T := NET_UNRELIABLE;
+ if Reliable
+ then T := NET_RELIABLE
+ else T := NET_UNRELIABLE;
if (ID >= 0) then
begin
ENET_EVENT_TYPE_RECEIVE:
begin
//e_LogWritefln('RECEIVE: chan=%u', [NetEvent.channelID]);
- if (NetEvent.channelID = NET_CHAN_DOWNLOAD_EX) then
+ if (NetEvent.channelID = NET_CHAN_DOWNLOAD) then
begin
ProcessDownloadExPacket();
end
e_WriteLog('NET: Disconnected', TMsgType.Notify);
end;
-procedure g_Net_Client_Send(Reliable: Boolean; Chan: Byte = NET_CHAN_GAME);
+procedure g_Net_Client_Send(Reliable: Boolean);
var
T: Integer;
begin
- if (Reliable) then
- T := NET_RELIABLE
- else
- T := NET_UNRELIABLE;
+ if Reliable
+ then T := NET_RELIABLE
+ else T := NET_UNRELIABLE;
// write size first
NetBuf[T].Write(Integer(NetOut.CurSize));
NetInitDone := True;
end;
- NetHost := enet_host_create(nil, 1, NET_CHANS, 0, 0);
+ NetHost := enet_host_create(nil, 1, NET_CHANNELS, 0, 0);
if (NetHost = nil) then
begin
enet_address_set_host(@NetAddr, PChar(Addr(IP[1])));
NetAddr.port := Port;
- NetPeer := enet_host_connect(NetHost, @NetAddr, NET_CHANS, NET_PROTOCOL_VER);
+ NetPeer := enet_host_connect(NetHost, @NetAddr, NET_CHANNELS, NET_PROTOCOL_VER);
if (NetPeer = nil) then
begin
end;
end;
-procedure g_Net_SendData(Data: AByte; peer: pENetPeer; Reliable: Boolean; Chan: Byte = NET_CHAN_DOWNLOAD);
-var
- P: pENetPacket;
- F: enet_uint32;
- dataLength: Cardinal;
-begin
- dataLength := Length(Data);
-
- if Reliable
- then F := LongWord(ENET_PACKET_FLAG_RELIABLE)
- else F := 0;
-
- P := enet_packet_create(@Data[0], dataLength, F);
- if not Assigned(P) then exit;
-
- if peer <> nil
- then enet_peer_send(peer, Chan, P)
- else enet_host_broadcast(NetHost, Chan, P);
-
- enet_host_flush(NetHost);
-end;
-
function g_Net_IsHostBanned(IP: LongWord; Perm: Boolean = False): Boolean;
var
I: Integer;
diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index 73c65e358b9427b7486f9425cb1c0569d39f67c3..1eb3683759c40e6a12ab9b30ba1855a50b4c0f18 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
NetOut.Write(gGameSettings.Options);
NetOut.Write(gTime);
- g_Net_Host_Send(ID, True, NET_CHAN_SERVICE);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_Chat(Txt: string; Mode: Byte; ID: Integer = NET_EVERYONE);
NetOut.Write(Byte(NET_MSG_CHAT));
NetOut.Write(Txt);
NetOut.Write(Mode);
- g_Net_Host_Send(gPlayers[i].FClientID, True, NET_CHAN_CHAT);
+ g_Net_Host_Send(gPlayers[i].FClientID, True);
end;
Team := ID;
ID := NET_EVERYONE;
NetOut.Write(Byte(NET_MSG_CHAT));
NetOut.Write(Txt);
NetOut.Write(Mode);
- g_Net_Host_Send(ID, True, NET_CHAN_CHAT);
+ g_Net_Host_Send(ID, True);
end;
if Mode = NET_CHAT_SYSTEM then
NetOut.Write(Y);
NetOut.Write(Ang);
- g_Net_Host_Send(ID, False, NET_CHAN_GAME);
+ g_Net_Host_Send(ID, False);
end;
procedure MH_SEND_Sound(X, Y: Integer; Name: string; Pos: Boolean = True; ID: Integer = NET_EVERYONE);
else
NetOut.Write(Byte(0));
- g_Net_Host_Send(ID, False, NET_CHAN_GAME);
+ g_Net_Host_Send(ID, False);
end;
procedure MH_SEND_CreateShot(Proj: LongInt; ID: Integer = NET_EVERYONE);
NetOut.Write(Shots[Proj].Obj.Vel.X);
NetOut.Write(Shots[Proj].Obj.Vel.Y);
- g_Net_Host_Send(ID, True, NET_CHAN_SHOTS);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_UpdateShot(Proj: LongInt; ID: Integer = NET_EVERYONE);
NetOut.Write(Shots[Proj].Obj.Vel.X);
NetOut.Write(Shots[Proj].Obj.Vel.Y);
- g_Net_Host_Send(ID, False, NET_CHAN_SHOTS);
+ g_Net_Host_Send(ID, False);
end;
procedure MH_Send_DeleteShot(Proj: LongInt; X, Y: LongInt; Loud: Boolean = True; ID: Integer = NET_EVERYONE);
NetOut.Write(X);
NetOut.Write(Y);
- g_Net_Host_Send(ID, True, NET_CHAN_SHOTS);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_GameStats(ID: Integer = NET_EVERYONE);
NetOut.Write(gCoopSecretsFound);
end;
- g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_CoopStats(ID: Integer = NET_EVERYONE);
end else
NetOut.Write(Byte(0));
- g_Net_Host_Send(ID, True, NET_CHAN_SERVICE);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_FlagEvent(EvType: Byte; Flag: Byte; PID: Word; Quiet: Boolean = False; ID: Integer = NET_EVERYONE);
NetOut.Write(gFlags[Flag].Obj.Vel.Y);
NetOut.Write(Byte(gFlags[Flag].Direction));
- g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_FlagPos(Flag: Byte; ID: Integer = NET_EVERYONE);
NetOut.Write(gFlags[Flag].Obj.Vel.X);
NetOut.Write(gFlags[Flag].Obj.Vel.Y);
- g_Net_Host_Send(ID, False, NET_CHAN_IMPORTANT);
+ g_Net_Host_Send(ID, False);
end;
procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE);
NetOut.Write(gGameSettings.MaxLives);
NetOut.Write(gGameSettings.Options);
- g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
+ g_Net_Host_Send(ID, True);
end;
// PLAYER (SEND)
NetOut.Write(P.FColor.B);
NetOut.Write(P.Team);
- g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT)
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_PlayerPos(Reliable: Boolean; PID: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(GameAccelY);
end;
- g_Net_Host_Send(ID, Reliable, NET_CHAN_PLAYERPOS);
+ g_Net_Host_Send(ID, Reliable);
end;
procedure MH_SEND_PlayerStats(PID: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(FSpawnInvul);
end;
- g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_PlayerDamage(PID: Word; Kind: Byte; Attacker, Value: Word; VX, VY: Integer; ID: Integer = NET_EVERYONE);
NetOut.Write(VX);
NetOut.Write(VY);
- g_Net_Host_Send(ID, False, NET_CHAN_PLAYER);
+ g_Net_Host_Send(ID, False);
end;
procedure MH_SEND_PlayerDeath(PID: Word; KillType, DeathType: Byte; Attacker: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(DeathType);
NetOut.Write(Attacker);
- g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_PlayerFire(PID: Word; Weapon: Byte; X, Y, AX, AY: Integer; ShotID: Integer = -1; ID: Integer = NET_EVERYONE);
NetOut.Write(AY);
NetOut.Write(ShotID);
- g_Net_Host_Send(ID, True, NET_CHAN_SHOTS);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_PlayerDelete(PID: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(Byte(NET_MSG_PLRDEL));
NetOut.Write(PID);
- g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_PlayerSettings(PID: Word; Mdl: string = ''; ID: Integer = NET_EVERYONE);
NetOut.Write(Pl.FColor.B);
NetOut.Write(Pl.Team);
- g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
+ g_Net_Host_Send(ID, True);
end;
// ITEM (SEND)
NetOut.Write(it.Obj.Vel.X);
NetOut.Write(it.Obj.Vel.Y);
- g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(IID);
NetOut.Write(Byte(Quiet));
- g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_ItemPos(IID: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(it.Obj.Vel.X);
NetOut.Write(it.Obj.Vel.Y);
- g_Net_Host_Send(ID, False, NET_CHAN_LARGEDATA);
+ g_Net_Host_Send(ID, False);
end;
// PANEL
NetOut.Write(AnimLoop);
end;
- g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE);
if TP.moveOnce then mpflags := mpflags or 2;
NetOut.Write(Byte(mpflags));
- g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
+ g_Net_Host_Send(ID, True);
end;
// TRIGGER
NetOut.Write(Byte(GameDirection));
end;
- g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_MonsterPos(UID: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(Byte(GameDirection));
end;
- g_Net_Host_Send(ID, False, NET_CHAN_MONSTERPOS);
+ g_Net_Host_Send(ID, False);
end;
procedure MH_SEND_MonsterState(UID: Word; ForcedAnim: Byte = 255; ID: Integer = NET_EVERYONE);
NetOut.Write(FFireTime);
end;
- g_Net_Host_Send(ID, True, NET_CHAN_MONSTER);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_MonsterShot(UID: Word; X, Y, VX, VY: Integer; ID: Integer = NET_EVERYONE);
NetOut.Write(VX);
NetOut.Write(VY);
- g_Net_Host_Send(ID, True, NET_CHAN_MONSTER);
+ g_Net_Host_Send(ID, True);
end;
procedure MH_SEND_MonsterDelete(UID: Word; ID: Integer = NET_EVERYONE);
NetOut.Write(Byte(NET_MSG_MDEL));
NetOut.Write(UID);
- g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
+ g_Net_Host_Send(ID, True);
end;
// MISC
NetOut.Write(Byte(NET_MSG_TIME_SYNC));
NetOut.Write(Time);
- g_Net_Host_Send(ID, False, NET_CHAN_SERVICE);
+ g_Net_Host_Send(ID, False);
end;
procedure MH_SEND_VoteEvent(EvType: Byte;
NetOut.Write(StrArg1);
NetOut.Write(StrArg2);
- g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT);
+ g_Net_Host_Send(ID, True);
end;
// CLIENT MESSAGES //
NetOut.Write(gPlayer1Settings.SwitchToEmpty);
NetOut.Write(gPlayer1Settings.SkipFist);
- g_Net_Client_Send(True, NET_CHAN_SERVICE);
+ g_Net_Client_Send(True);
end;
procedure MC_SEND_Chat(Txt: string; Mode: Byte);
NetOut.Write(Txt);
NetOut.Write(Mode);
- g_Net_Client_Send(True, NET_CHAN_CHAT);
+ g_Net_Client_Send(True);
end;
procedure MC_SEND_PlayerPos();
NetOut.Write(WeaponAct);
NetOut.Write(WeaponSelect);
//e_WriteLog(Format('S:ws=%d', [WeaponSelect]), MSG_WARNING);
- g_Net_Client_Send(True, NET_CHAN_PLAYERPOS);
+ g_Net_Client_Send(True);
//kBytePrev := kByte;
//kDirPrev := gPlayer1.Direction;
NetOut.Write(Byte(NET_MSG_VOTE_EVENT));
NetOut.Write(Byte(Start));
NetOut.Write(Command);
- g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
+ g_Net_Client_Send(True);
end;
procedure MC_SEND_PlayerSettings();
NetOut.Write(gPlayer1Settings.SwitchToEmpty);
NetOut.Write(gPlayer1Settings.SkipFist);
- g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
+ g_Net_Client_Send(True);
end;
procedure MC_SEND_FullStateRequest();
begin
NetOut.Write(Byte(NET_MSG_REQFST));
- g_Net_Client_Send(True, NET_CHAN_SERVICE);
+ g_Net_Client_Send(True);
end;
procedure MC_SEND_CheatRequest(Kind: Byte);
NetOut.Write(Byte(NET_MSG_CHEAT));
NetOut.Write(Kind);
- g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
+ g_Net_Client_Send(True);
end;
procedure MC_SEND_RCONPassword(Password: string);
begin
NetOut.Write(Byte(NET_MSG_RCON_AUTH));
NetOut.Write(Password);
- g_Net_Client_Send(True, NET_CHAN_SERVICE);
+ g_Net_Client_Send(True);
end;
procedure MC_SEND_RCONCommand(Cmd: string);
begin
NetOut.Write(Byte(NET_MSG_RCON_CMD));
NetOut.Write(Cmd);
- g_Net_Client_Send(True, NET_CHAN_SERVICE);
+ g_Net_Client_Send(True);
end;