Skip to content

Commit

Permalink
fix misc client-side demo bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
sauerbraten committed Jun 25, 2022
1 parent 19c28fc commit c2ac835
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 190 deletions.
59 changes: 25 additions & 34 deletions patches/anticheat.patch
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
Subject: [PATCH] add anticheat.patch, clean up Makefile, use Zig to
cross-compile

---
src/anticheat/anticheat.cpp | 637 +++++++++++++++++++++++++++
src/engine/engine.h | 6 +
src/engine/main.cpp | 17 +
src/engine/movie.cpp | 4 +
src/engine/server.cpp | 17 +
src/engine/sound.cpp | 4 +
src/engine/texture.cpp | 5 +-
src/fpsgame/client.cpp | 19 +
src/fpsgame/game.h | 35 +-
src/fpsgame/server.cpp | 60 ++-
src/p1xbraten/capability_probing.cpp | 3 +
src/shared/cube.h | 2 +-
src/shared/igame.h | 14 +-
13 files changed, 817 insertions(+), 6 deletions(-)
create mode 100644 src/anticheat/anticheat.cpp

diff --git src/anticheat/anticheat.cpp src/anticheat/anticheat.cpp
new file mode 100644
index 0000000..2fe07ee
Expand Down Expand Up @@ -846,10 +826,10 @@ index c5ae27e..6b87170 100644
if(remote) stopfollowing();
ignores.setsize(0);
connected = remote = false;
@@ -2076,7 +2079,23 @@ namespace game
managedgamedemonextmatch = val!=0;
@@ -2091,7 +2094,23 @@ namespace game
}
else enddemorecord(true);
break;
}
+#ifdef ANTICHEAT
+ case N_P1X_ANTICHEAT_BEGINSESSION:
+ triggeranticheatsession();
Expand Down Expand Up @@ -877,18 +857,15 @@ index 0a4c901..4e9fe3a 100644
@@ -215,6 +215,7 @@ enum

// protocol extensions
static const char * const CAP_PROBE_CLIENT_DEMO_UPLOAD = "capability_probe_protocol_extension_p1x_client_demo_upload";
static const char * const CAP_PROBE_CLIENT_DEMO_UPLOAD = "capability_probe_protocol_extension_p1x_client_demo_upload_v2";
+static const char * const CAP_PROBE_ANTICHEAT = "capability_probe_protocol_extension_p1x_anticheat";

// network messages codes, c2s, c2c, s2c

@@ -245,8 +246,11 @@ enum
N_INITTOKENS, N_TAKETOKEN, N_EXPIRETOKENS, N_DROPTOKENS, N_DEPOSITTOKENS, N_STEALTOKENS,
N_SERVCMD,
N_DEMOPACKET,
- N_P1X_SETIP = 900, // only from proxy to server
+ N_P1X_SETIP = 900, // only from proxy to server (see addtrustedproxyip cmd)
N_P1X_CLIENT_DEMO_UPLOAD_SUPPORTED = 1000, N_P1X_RECORDDEMO, // guarded by CAP_PROBE_CLIENT_DEMO_UPLOAD
@@ -248,6 +248,9 @@ enum
N_P1X_SETIP = 900, // only from proxy to server (see addtrustedproxyip cmd)
// N_P1X_CLIENT_DEMO_UPLOAD_SUPPORTED = 1000, N_P1X_RECORDDEMO, // legacy
N_P1X_CLIENT_DEMO_UPLOAD_SUPPORTED = 1002, N_P1X_RECORDDEMO, // guarded by CAP_PROBE_CLIENT_DEMO_UPLOAD
+#ifdef ANTICHEAT
+ N_P1X_ANTICHEAT_SUPPORTED = 2000, N_P1X_ANTICHEAT_BEGINSESSION, N_P1X_ANTICHEAT_MESSAGE, N_P1X_ANTICHEAT_VIOLATION, N_P1X_ANTICHEAT_ENDSESSION, // guarded by CAP_PROBE_ANTICHEAT
+#endif
Expand All @@ -906,9 +883,9 @@ index 0a4c901..4e9fe3a 100644
};

@@ -886,6 +893,14 @@ namespace game
extern bool managedgamedemonextmatch;
extern string managedgamedemofname;
extern void sendclientdemo();
// managed games
extern void handlecapprobe(const char *msg);
extern void sendclientdemo(stream *demo);
+
+#ifdef ANTICHEAT
+ // anticheat
Expand Down Expand Up @@ -1081,6 +1058,20 @@ index 232c554..286bdfa 100644
}

}
diff --git src/p1xbraten/clientdemo.cpp src/p1xbraten/clientdemo.cpp
index 4272bd7..8b407e5 100644
--- src/p1xbraten/clientdemo.cpp
+++ src/p1xbraten/clientdemo.cpp
@@ -55,6 +55,9 @@ namespace game {
case N_AUTHTRY: case N_AUTHCHAL: case N_AUTHANS: case N_REQAUTH:
case N_P1X_SETIP:
case N_P1X_RECORDDEMO:
+#ifdef ANTICHEAT
+ case N_P1X_ANTICHEAT_BEGINSESSION: case N_P1X_ANTICHEAT_MESSAGE: case N_P1X_ANTICHEAT_ENDSESSION:
+#endif
return;
}
int stamp[3] = { totalmillis-demostartmillis, chan, len };
diff --git src/shared/cube.h src/shared/cube.h
index be7755c..c153591 100644
--- src/shared/cube.h
Expand Down
87 changes: 52 additions & 35 deletions patches/clientdemo.patch
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ index f6f7555..59b8c54 100644
+ }
+ }
};

extern captureclientmode capturemode;
diff --git src/fpsgame/client.cpp src/fpsgame/client.cpp
index 522d32a..b0cc1c8 100644
Expand All @@ -45,7 +45,7 @@ index 522d32a..b0cc1c8 100644
void printname()
{
@@ -568,6 +569,7 @@ namespace game

void changemapserv(const char *name, int mode) // forced map change from the server
{
+ if(demorecord) enddemorecord();
Expand All @@ -63,14 +63,14 @@ index 522d32a..b0cc1c8 100644
@@ -980,7 +983,7 @@ namespace game
VARP(teamcolorchat, 0, 1, 1);
const char *chatcolorname(fpsent *d) { return teamcolorchat ? teamcolorname(d, NULL) : colorname(d); }

- void toserver(char *text) { conoutf(CON_CHAT, "%s:\f0 %s", chatcolorname(player1), text); addmsg(N_TEXT, "rcs", player1, text); }
+ void toserver(char *text) { conoutf(CON_CHAT, "%s:\f0 %s", chatcolorname(player1), text); addmsg(N_TEXT, "rcs", player1, text); if(demorecord) recordmsg(N_TEXT, "rcs", player1, text); }
COMMANDN(say, toserver, "C");

void sayteam(char *text) { conoutf(CON_TEAMCHAT, "\fs\f8[team]\fr %s: \f8%s", chatcolorname(player1), text); addmsg(N_SAYTEAM, "rcs", player1, text); }
@@ -994,6 +997,7 @@ namespace game

static void sendposition(fpsent *d, packetbuf &q)
{
+ int offset = q.length();
Expand All @@ -83,7 +83,7 @@ index 522d32a..b0cc1c8 100644
}
+ if(demorecord && (d==player1 || d->ai)) recordpacket(0, q.buf+offset, q.length());
}

void sendposition(fpsent *d, bool reliable)
@@ -1115,9 +1120,21 @@ namespace game
void c2sinfo(bool force) // send update to the server
Expand All @@ -110,13 +110,13 @@ index 522d32a..b0cc1c8 100644
}
@@ -1826,7 +1843,9 @@ namespace game
}

case N_PONG:
+ if(demopacket) { getint(p); break; }
addmsg(N_CLIENTPING, "i", player1->ping = (player1->ping*5+totalmillis-getint(p))/6);
+ if(demorecord) recordmsg(N_CLIENTPING, "i", player1->ping);
break;

case N_CLIENTPING:
@@ -2101,6 +2120,7 @@ namespace game
void parsepacketclient(int chan, packetbuf &p) // processes any updates from the server
Expand All @@ -132,7 +132,7 @@ index a3d4ea8..1e6b8b0 100644
+++ src/fpsgame/ctf.h
@@ -447,6 +447,9 @@ struct ctfclientmode : clientmode
}

void initclient(clientinfo *ci, packetbuf &p, bool connecting)
+#else
+ void initdemoclient(packetbuf &p)
Expand All @@ -159,7 +159,7 @@ index a3d4ea8..1e6b8b0 100644
@@ -480,6 +489,7 @@ struct ctfclientmode : clientmode
}
}

+#ifdef SERVMODE
void parseflags(ucharbuf &p, bool commit)
{
Expand Down Expand Up @@ -191,11 +191,11 @@ index 7dc7de0..f5328cb 100644
@@ -688,6 +688,7 @@ namespace game
disablezoom();
lasthit = 0;

+ if(remote && demonextmatch) setupdemorecord();
execident("mapstart");
}

@@ -743,12 +744,16 @@ namespace game
if(!d || d==player1)
{
Expand Down Expand Up @@ -223,19 +223,19 @@ index b59407a..64a92ad 100644
virtual bool aipursue(fpsent *d, ai::aistate &b) { return false; }
+ virtual void initdemoclient(packetbuf &p) {}
};

extern clientmode *cmode;
@@ -752,8 +753,10 @@ namespace game
const char *mastermodeicon(int n, const char *unknown);

// client
- extern bool connected, remote, demoplayback;
+ extern bool connected, remote, demoplayback, gamepaused;
extern string servinfo;
+ extern int mastermode, gamespeed;
+ extern hashset<teaminfo> teaminfos;
extern vector<uchar> messages;

extern int parseplayer(const char *arg);
@@ -860,6 +863,14 @@ namespace game
extern int chooserandomplayermodel(int seed);
Expand All @@ -246,11 +246,11 @@ index b59407a..64a92ad 100644
+ extern bool demonextmatch;
+ extern stream *demorecord;
+ extern void setupdemorecord();
+ extern void recordpacket(int chan, void *data, int len);
+ extern void recordpacket(int chan, uchar *data, int len);
+ extern bool recordmsg(int type, const char *fmt = NULL, ...);
+ extern void enddemorecord();
}

#include "fragmessages.h"
diff --git src/fpsgame/scoreboard.cpp src/fpsgame/scoreboard.cpp
index 1833375..6433a9b 100644
Expand All @@ -259,10 +259,10 @@ index 1833375..6433a9b 100644
@@ -22,7 +22,7 @@ namespace game
MOD(VARP, showdamage, 0, 0, 2);
MOD(VARP, showdamagereceived, 0, 0, 1);

- static hashset<teaminfo> teaminfos;
+ hashset<teaminfo> teaminfos;

void clearteaminfo()
{
diff --git src/fpsgame/weapon.cpp src/fpsgame/weapon.cpp
Expand All @@ -286,14 +286,14 @@ index f495ed6..4810e0d 100644
+ int(from.x*DMF), int(from.y*DMF), int(from.z*DMF),
+ int(to.x*DMF), int(to.y*DMF), int(to.z*DMF));
}

d->gunwait = guns[d->gunselect].attackdelay;
diff --git src/p1xbraten/clientdemo.cpp src/p1xbraten/clientdemo.cpp
new file mode 100644
index 0000000..839b0a9
--- /dev/null
+++ src/p1xbraten/clientdemo.cpp
@@ -0,0 +1,300 @@
@@ -0,0 +1,317 @@
+#include "game.h"
+
+// client-side demo recording works mostly the same as server-side:
Expand Down Expand Up @@ -321,15 +321,36 @@ index 0000000..839b0a9
+ {
+ if(!demorecord) return;
+ DELETEP(demorecord);
+ conoutf("stopped client demo recording");
+ if(!demo) return;
+ DELETEP(demo);
+ conoutf("stopped client demo recording");
+ }
+
+ void recordpacket(int chan, void *data, int len)
+
+ void recordpacket(int chan, uchar *data, int len)
+ {
+ if(!demorecord) return;
+ int stamp[3] = { totalmillis-demostartmillis, chan, len };
+ if(!demorecord || !len) return;
+ // peek message type
+ int type = (schar)data[0];
+ if(type==-128 && len > 3)
+ {
+ type = data[1];
+ type |= ((schar)data[2])<<8;
+ }
+ else if(type==-127 && len > 5)
+ {
+ type = data[1];
+ type |= ((schar)data[2])<<8;
+ type |= ((schar)data[3])<<16;
+ type |= ((schar)data[4])<<24;
+ }
+ // skip certain packets
+ switch (type) {
+ case N_SENDDEMOLIST:
+ case N_AUTHTRY: case N_AUTHCHAL: case N_AUTHANS: case N_REQAUTH:
+ return;
+ }
+ int stamp[3] = { lastmillis-demostartmillis, chan, len };
+ lilswap(stamp, 3);
+ demorecord->write(stamp, sizeof(stamp));
+ demorecord->write(data, len);
Expand Down Expand Up @@ -390,7 +411,7 @@ index 0000000..839b0a9
+ putint(p, gamemode);
+ putint(p, 0); // notgotitems = false
+ putint(p, N_TIMEUP);
+ putint(p, lastmillis < maplimit && !intermission ? max((maplimit - totalmillis)/1000, 1) : 0);
+ putint(p, intermission ? 0 : max((maplimit - lastmillis)/1000, 1));
+ putint(p, N_ITEMLIST);
+ loopv(entities::ents) if(entities::ents[i]->spawned())
+ {
Expand Down Expand Up @@ -458,7 +479,7 @@ index 0000000..839b0a9
+
+ void setupdemorecord()
+ {
+ if(!m_mp(gamemode) || m_edit || m_collect || demo || demorecord) return;
+ if(!m_mp(gamemode) || m_collect || demoplayback || demorecord) return; // todo: collect init packet
+
+ string tname;
+ tname[0] = '\0';
Expand Down Expand Up @@ -490,7 +511,7 @@ index 0000000..839b0a9
+ lilswap(&hdr.version, 2);
+ demorecord->write(&hdr, sizeof(demoheader));
+
+ demostartmillis = totalmillis;
+ demostartmillis = lastmillis;
+
+ packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
+ welcomepacket(p);
Expand All @@ -501,17 +522,13 @@ index 0000000..839b0a9
+ {
+ switch (val)
+ {
+ case 0: case 1: // (un)schedule for next match
+ {
+ demonextmatch = val==1;
+ conoutf("client demo recording is %s for next match", demonextmatch ? "enabled" : "disabled");
+ case 0: // stop recording
+ enddemorecord();
+ break;
+ }
+ // case 1: // unused, legacy
+ case 2: // start immediately
+ {
+ setupdemorecord();
+ break;
+ }
+ }
+ }
+ ICOMMAND(recordclientdemo, "i", (int *val), recordclientdemo(*val));
Expand Down
Loading

0 comments on commit c2ac835

Please sign in to comment.