-
Notifications
You must be signed in to change notification settings - Fork 3
/
modversion.patch
218 lines (205 loc) · 6.98 KB
/
modversion.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
Index: src/engine/engine.h
===================================================================
--- src/engine/engine.h (revision 6502)
+++ src/engine/engine.h (working copy)
@@ -407,6 +407,8 @@
extern void checksleep(int millis);
extern void clearsleep(bool clearoverrides = true);
+extern int naturalsort(const char *a, const char *b);
+
// console
extern void processtextinput(const char *str, int len);
extern void processkey(int code, bool isdown, int modstate = 0);
@@ -431,6 +433,8 @@
};
extern int initing, numcpus;
+extern void migratep1xbraten();
+
enum
{
CHANGE_GFX = 1<<0,
Index: src/engine/main.cpp
===================================================================
--- src/engine/main.cpp (revision 6502)
+++ src/engine/main.cpp (working copy)
@@ -1330,6 +1330,8 @@
identflags |= IDF_PERSIST;
+ migratep1xbraten();
+
logoutf("init: mainloop");
if(execfile("once.cfg", false)) remove(findfile("once.cfg", "rb"));
Index: src/p1xbraten/version.cpp
===================================================================
--- src/p1xbraten/version.cpp (nonexistent)
+++ src/p1xbraten/version.cpp (working copy)
@@ -0,0 +1,22 @@
+#include "engine.h"
+
+MOD(SVARP, p1xbratenversion, "");
+
+void lockversion()
+{
+ ident *id = getident("p1xbratenversion");
+ if(!id) { conoutf(CON_ERROR, "p1xbratenversion is undefined!"); return; }
+ if(!(id->flags&IDF_READONLY)) id->flags += IDF_READONLY;
+}
+
+void migratep1xbraten()
+{
+ const char *version = "<git-dev>"; // replaced in CI build
+ if(naturalsort(p1xbratenversion, version) == -1)
+ {
+ // we're newer, run migrations
+ }
+ setsvar("p1xbratenversion", version);
+ lockversion();
+ conoutf("p1xbraten version: %s", version);
+}
Index: src/fpsgame/client.cpp
===================================================================
--- src/fpsgame/client.cpp (revision 6502)
+++ src/fpsgame/client.cpp (working copy)
@@ -308,6 +308,14 @@
}
ICOMMAND(getclienticon, "i", (int *cn), result(getclienticon(*cn)));
+ const char *getclientp1xbratenversion(int cn)
+ {
+ fpsent *d = getclient(cn);
+ if(d==player1) return p1xbratenversion;
+ return d ? d->p1xbratenversion.tostring() : "";
+ }
+ ICOMMAND(getclientp1xbratenversion, "i", (int *cn), result(getclientp1xbratenversion(*cn)));
+
bool ismaster(int cn)
{
fpsent *d = getclient(cn);
@@ -1086,6 +1094,7 @@
sendstring("", p);
}
sendclientpacket(p.finalize(), 1);
+ broadcastp1xbratenversion();
}
void updatepos(fpsent *d)
@@ -1406,6 +1415,7 @@
{
conoutf("\f0join:\f7 %s", colorname(d, text));
if(needclipboard >= 0) needclipboard++;
+ broadcastp1xbratenversion();
}
copystring(d->name, text, MAXNAMELEN+1);
getstring(text, p);
@@ -1433,6 +1443,7 @@
int model = getint(p);
if(d)
{
+ if(setp1xbratenversion(d, model)) break;
d->playermodel = model;
if(d->ragdoll) cleanragdoll(d);
}
Index: src/fpsgame/game.h
===================================================================
--- src/fpsgame/game.h (revision 6502)
+++ src/fpsgame/game.h (working copy)
@@ -557,10 +557,11 @@
int playermodel;
ai::aiinfo *ai;
int ownernum, lastnode;
+ semver p1xbratenversion;
vec muzzle;
- fpsent() : weight(100), clientnum(-1), privilege(PRIV_NONE), lastupdate(0), plag(0), ping(0), lifesequence(0), respawned(-1), suicided(-1), lastpain(0), attacksound(-1), attackchan(-1), idlesound(-1), idlechan(-1), frags(0), flags(0), deaths(0), totaldamage(0), totalshots(0), edit(NULL), smoothmillis(-1), playermodel(-1), ai(NULL), ownernum(-1), muzzle(-1, -1, -1)
+ fpsent() : weight(100), clientnum(-1), privilege(PRIV_NONE), lastupdate(0), plag(0), ping(0), lifesequence(0), respawned(-1), suicided(-1), lastpain(0), attacksound(-1), attackchan(-1), idlesound(-1), idlechan(-1), frags(0), flags(0), deaths(0), totaldamage(0), totalshots(0), edit(NULL), smoothmillis(-1), playermodel(-1), ai(NULL), ownernum(-1), p1xbratenversion(0, 0, 0), muzzle(-1, -1, -1)
{
name[0] = team[0] = info[0] = 0;
respawn();
@@ -764,6 +765,8 @@
extern void forceintermission();
extern void c2sinfo(bool force = false);
extern void sendposition(fpsent *d, bool reliable = false);
+ extern void broadcastp1xbratenversion();
+ extern bool setp1xbratenversion(fpsent *d, int version);
// monster
struct monster;
Index: src/p1xbraten/detection.cpp
===================================================================
--- src/p1xbraten/detection.cpp (nonexistent)
+++ src/p1xbraten/detection.cpp (working copy)
@@ -0,0 +1,23 @@
+#include "game.h"
+
+namespace game {
+ #define P1XBRATEN_VERSION_PREFIX (uchar(69))
+
+ MOD(VARP, enablep1xbratendetection, 0, 1, 1);
+
+ void broadcastp1xbratenversion()
+ {
+ if(!enablep1xbratendetection) return;
+ static const semver v(p1xbratenversion);
+ addmsg(N_SWITCHMODEL, "ri", P1XBRATEN_VERSION_PREFIX<<24 | int(v.maj) << 16 | int(v.min) << 8 | int(v.patch));
+ addmsg(N_SWITCHMODEL, "ri", player1->playermodel);
+ }
+
+ bool setp1xbratenversion(fpsent *d, int version)
+ {
+ if((version>>24)!=P1XBRATEN_VERSION_PREFIX) return false;
+ if(!enablep1xbratendetection) return true;
+ d->p1xbratenversion = semver((version>>16)&0xF, (version>>8)&0xF, version&0xF);
+ return true;
+ }
+}
Index: src/shared/iengine.h
===================================================================
--- src/shared/iengine.h (revision 6502)
+++ src/shared/iengine.h (working copy)
@@ -581,3 +581,4 @@
extern void g3d_resetcursor();
extern void g3d_limitscale(float scale);
+extern char *p1xbratenversion;
Index: src/shared/tools.h
===================================================================
--- src/shared/tools.h (revision 6502)
+++ src/shared/tools.h (working copy)
@@ -1404,5 +1404,45 @@
bool check(enet_uint32 host) const { return (host & mask) == ip; }
};
+struct semver {
+ uchar maj = 0, min = 0, patch = 0;
+
+ semver(uchar maj, uchar min, uchar patch) : maj(maj), min(min), patch(patch)
+ {
+ //
+ }
+
+ semver(const char *version)
+ {
+ char *v = newstring(version);
+ const char *numstart = v;
+
+ while(isdigit(*v)) v++;
+ if(*v!='.') return;
+ *v = '\0';
+ maj = uchar(strtoul(numstart, NULL, 0));
+ *v = '.';
+ v++;
+
+ numstart = v;
+ while(isdigit(*v)) v++;
+ if(*v!='.') return;
+ *v = '\0';
+ min = uchar(strtoul(numstart, NULL, 0));
+ *v = '.';
+ v++;
+ if(!*v) return;
+
+ numstart = v;
+ patch = uchar(strtoul(numstart, NULL, 0));
+ }
+
+ char *tostring()
+ {
+ defformatstring(s, "%d.%d.%d", maj, min, patch);
+ return newstring(s);
+ }
+};
+
#endif