]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Registry: network and verify checksums on connect
authorTimePath <andrew.hardaker1995@gmail.com>
Fri, 6 Nov 2015 02:34:28 +0000 (13:34 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Fri, 6 Nov 2015 02:34:28 +0000 (13:34 +1100)
20 files changed:
qcsrc/client/main.qc
qcsrc/common/buffs/all.qh
qcsrc/common/constants.qh
qcsrc/common/deathtypes/all.qh
qcsrc/common/effects/all.qh
qcsrc/common/items/all.qh
qcsrc/common/mapinfo.qh
qcsrc/common/minigames/cl_minigames.qh
qcsrc/common/minigames/sv_minigames.qh
qcsrc/common/monsters/all.qh
qcsrc/common/mutators/mutator/waypoints/all.qh
qcsrc/common/nades/all.qh
qcsrc/common/turrets/all.qh
qcsrc/common/vehicles/all.qh
qcsrc/common/weapons/all.qh
qcsrc/lib/_all.inc
qcsrc/lib/net.qh
qcsrc/lib/registry.qh
qcsrc/lib/registry_net.qh [new file with mode: 0644]
qcsrc/server/cl_client.qc

index 523786e4165dd67aecb9e7c66d217ccfb77c02af..badc78ce69fca9ca08a318455741b88fdedccc0e 100644 (file)
@@ -934,8 +934,6 @@ NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
 
 NET_HANDLE(ENT_CLIENT_INIT, bool isnew)
 {
-       make_pure(this);
-
        nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
 
        hook_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
index 073e3b3aad0197377ab47dc6d71e5069834e57e5..beabaa75511eb3a65c707fb27f812707a235e45b 100644 (file)
@@ -11,6 +11,7 @@
 REGISTRY(Buffs, BITS(4))
 #define Buffs_from(i) _Buffs_from(i, BUFF_Null)
 REGISTER_REGISTRY(RegisterBuffs)
+REGISTRY_CHECK(Buffs)
 
 #define REGISTER_BUFF(id) \
     REGISTER(RegisterBuffs, BUFF, Buffs, id, m_id, NEW(Buff)); \
index 8c94c37ca94da55b17fbf6b4d8f445a2fc92d5d2..192b8f6a1bd04174469e25af57d09f3269f792cb 100644 (file)
@@ -53,6 +53,13 @@ const int RACE_NET_SERVER_RANKINGS = 11;
 const int RACE_NET_SERVER_STATUS = 12;
 const int RANKINGS_CNT = 15;
 
+REGISTER_NET_LINKED(_ENT_CLIENT_INIT)
+#ifdef CSQC
+NET_HANDLE(_ENT_CLIENT_INIT, bool isnew) { return true; }
+#endif
+/** Sent as a temp entity from a persistent linked entity */
+REGISTER_NET_TEMP(ENT_CLIENT_INIT)
+
 REGISTER_NET_LINKED(ENT_CLIENT_ENTCS)
 REGISTER_NET_LINKED(ENT_CLIENT_SCORES_INFO)
 REGISTER_NET_LINKED(ENT_CLIENT_SCORES)
@@ -60,7 +67,6 @@ REGISTER_NET_LINKED(ENT_CLIENT_TEAMSCORES)
 REGISTER_NET_LINKED(ENT_CLIENT_NAGGER) // flags [votecalledvote]
 REGISTER_NET_LINKED(ENT_CLIENT_RADARLINK) // flags [startorigin] [endorigin] [startcolor+16*endcolor]
 REGISTER_NET_LINKED(ENT_CLIENT_PROJECTILE)
-REGISTER_NET_LINKED(ENT_CLIENT_INIT)
 REGISTER_NET_LINKED(ENT_CLIENT_MAPVOTE)
 REGISTER_NET_LINKED(ENT_CLIENT_CLIENTDATA)
 REGISTER_NET_LINKED(ENT_CLIENT_RANDOMSEED)
index 42aa6bb52b29ddd568bb8a180b5eb9c1303aded4..b3a671d260fde17cd95175394112a9e25f99afc7 100644 (file)
@@ -6,6 +6,7 @@
 REGISTRY(Deathtypes, BITS(8))
 #define Deathtypes_from(i) _Deathtypes_from(i, NULL)
 REGISTER_REGISTRY(RegisterDeathtypes)
+REGISTRY_CHECK(Deathtypes)
 
 .entity death_msgself;
 .entity death_msgmurder;
index 87bd63e757ee52794d89b08361c8eef0ed644e4c..58284fb0e39711516830b2b2e6b0dba2b81d07eb 100644 (file)
@@ -11,6 +11,7 @@ void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt);
 REGISTRY(Effects, BITS(8))
 #define Effects_from(i) _Effects_from(i, EFFECT_Null)
 REGISTER_REGISTRY(RegisterEffects)
+REGISTRY_CHECK(Effects)
 #define EFFECT(istrail, name, realname) \
     REGISTER(RegisterEffects, EFFECT, Effects, name, m_id, Create_Effect_Entity(realname, istrail));
 
index 69805a568cb992c7a9ce153bb4e7a49f4b68588d..809398bb292fa907c1e4f0d1a074ff646236bfee 100644 (file)
@@ -12,6 +12,7 @@ REGISTER_REGISTRY(RegisterItems)
 #define REGISTER_ITEM(id, class) REGISTER(RegisterItems, ITEM, Items, id, m_id, NEW(class))
 
 REGISTRY_SORT(Items, 0)
+REGISTRY_CHECK(Items)
 STATIC_INIT(Items) { FOREACH(Items, true, LAMBDA(it.m_id = i)); }
 
 void Dump_Items();
index 04ea78e4c5e0ed34b96ea40efe521baff00141e4..055777bf8493b51e0e15eb79e966c69abcf220a0 100644 (file)
@@ -45,6 +45,7 @@ ENDCLASS(Gametype)
 REGISTRY(Gametypes, BITS(4))
 #define Gametypes_from(i) _Gametypes_from(i, NULL)
 REGISTER_REGISTRY(RegisterGametypes)
+REGISTRY_CHECK(Gametypes)
 int MAPINFO_TYPE_ALL;
 #define REGISTER_GAMETYPE(hname, sname, g_name, NAME, gteamplay, mutators, defaults, gdescription)          \
     int MAPINFO_TYPE_##NAME;                                                                                \
index ab5ffc7ea8697667421b20b8386d396065e2af5b..6fb461c6beed194767fcb93f9211b48e3adb72cc 100644 (file)
@@ -114,6 +114,7 @@ void HUD_MinigameMenu_CustomEntry(entity parent, string message, string event_ar
 REGISTRY(Minigames, BITS(3))
 #define Minigames_from(i) _Minigames_from(i, NULL)
 REGISTER_REGISTRY(RegisterMinigames)
+REGISTRY_CHECK(Minigames)
 #define REGISTER_MINIGAME(name,nicename) \
     REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
     void name##_hud_board(vector, vector); \
index 422e780819957e536fe5f845db6a4df7ffdd7767..f60b2d6dbaedae53314da1356aa1ed5f6a0e741d 100644 (file)
@@ -49,6 +49,7 @@ bool minigame_SendEntity(entity this, entity to, int sf);
 REGISTRY(Minigames, BITS(3))
 #define Minigames_from(i) _Minigames_from(i, NULL)
 REGISTER_REGISTRY(RegisterMinigames)
+REGISTRY_CHECK(Minigames)
 #define REGISTER_MINIGAME(name,nicename) \
     REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
     int name##_server_event(entity, string, ...); \
index 5e46e8a80b56e6c3c6c93259a3a4126b0f6acafa..fd5978c91d4291936c15d05698b9410540bb14af 100644 (file)
@@ -9,6 +9,7 @@ REGISTRY(Monsters, BITS(5))
 #define Monsters_from(i) _Monsters_from(i, MON_Null)
 #define get_monsterinfo(i) Monsters_from(i)
 REGISTER_REGISTRY(RegisterMonsters)
+REGISTRY_CHECK(Monsters)
 const int MON_FIRST = 1;
 #define MON_LAST (Monsters_COUNT - 1)
 /** If you register a new monster, make sure to add it to all.inc */
index e04629b6f2c8f9220639bf3469f24de2a175f515..3769412ec6b16e54788b76420e1f5f50699adecb 100644 (file)
@@ -6,6 +6,8 @@
 REGISTRY(Waypoints, BITS(6))
 #define Waypoints_from(i) _Waypoints_from(i, WP_Null)
 REGISTER_REGISTRY(RegisterWaypoints)
+REGISTRY_CHECK(Waypoints)
+
 /** If you register a new waypoint, make sure to add it to all.inc */
 #define REGISTER_WAYPOINT_(id, init) REGISTER(RegisterWaypoints, WP, Waypoints, id, m_id, init)
 
@@ -29,6 +31,8 @@ ENDCLASS(Waypoint)
 REGISTRY(RadarIcons, BITS(7))
 #define RadarIcons_from(i) _RadarIcons_from(i, RADARICON_NONE)
 REGISTER_REGISTRY(RegisterRadarIcons)
+REGISTRY_CHECK(RadarIcons)
+
 .int m_radaricon;
 #define REGISTER_RADARICON(id, num) REGISTER(RegisterRadarIcons, RADARICON, RadarIcons, id, m_id, new(RadarIcon)) { make_pure(this); this.m_radaricon = num; this.netname = #id; }
 
index 9b2b6ec35e3746fffdc57ab7aba72e14f06f8171..235dd97dd186dea4f40d970c4ef0930da8602bc1 100644 (file)
@@ -24,6 +24,8 @@ const int PROJECTILE_NADE_MONSTER_BURN = 83;
 REGISTRY(Nades, BITS(4))
 #define Nades_from(i) _Nades_from(i, NADE_TYPE_Null)
 REGISTER_REGISTRY(RegisterNades)
+REGISTRY_CHECK(Nades)
+
 #define REGISTER_NADE(id) REGISTER(RegisterNades, NADE_TYPE, Nades, id, m_id, NEW(Nade))
 
 CLASS(Nade, Object)
index 0848478bfd9d8a4c65ac560e0000e07cb33c62a6..fa6ef43d423c0aaeed39086f324d6f0be8d1b2b9 100644 (file)
@@ -10,6 +10,7 @@ REGISTRY(Turrets, BITS(5))
 #define Turrets_from(i) _Turrets_from(i, TUR_Null)
 #define get_turretinfo(i) Turrets_from(i)
 REGISTER_REGISTRY(RegisterTurrets)
+REGISTRY_CHECK(Turrets)
 
 
 GENERIC_COMMAND(dumpturrets, "Dump all turrets into turrets_dump.txt")
index f5d643431b2a4cad714abfd8c6cfc6e700deada3..d2d943c4e4d2afe88fa72e3d3108adbaf72694ed 100644 (file)
@@ -7,6 +7,8 @@ REGISTRY(Vehicles, BITS(3))
 #define Vehicles_from(i) _Vehicles_from(i, VEH_Null)
 #define get_vehicleinfo(i) Vehicles_from(i)
 REGISTER_REGISTRY(RegisterVehicles)
+REGISTRY_CHECK(Vehicles)
+
 const int VEH_FIRST = 1;
 #define VEH_LAST (Vehicles_COUNT - 1)
 
index 5844049176eabb9d5dd4ad747898ec191fb6c743..10e804b479be2c3ab761b7c839258d705a1e1eb3 100644 (file)
@@ -140,6 +140,7 @@ REGISTER_WEAPON(Null, NEW(Weapon));
 #define WEP_IMPULSE_END bound(WEP_IMPULSE_BEGIN, WEP_IMPULSE_BEGIN + (Weapons_COUNT - 1) - 1, 253)
 
 REGISTRY_SORT(Weapons, WEP_HARDCODED_IMPULSES + 1)
+REGISTRY_CHECK(Weapons)
 
 STATIC_INIT(register_weapons_done)
 {
index 4169788148bc3616855b1db7aa060f6b057b9c1d..cffa8f7223112bd286813b5a8d98b926b81ddcd6 100644 (file)
@@ -55,6 +55,7 @@
 #include "progname.qh"
 #include "random.qc"
 #include "registry.qh"
+#include "registry_net.qh"
 #include "replicate.qh"
 #include "self.qh"
 #include "sortlist.qc"
index 7e3a1f1cbcc5569e71aa4f081beced5b27ddb074..f6013f97a783c757060a65bf547c26ae22e5f24c 100644 (file)
@@ -112,6 +112,7 @@ REGISTRY(LinkedEntities, BITS(8) - 1)
 #define LinkedEntities_from(i) _LinkedEntities_from(i, NULL)
 REGISTER_REGISTRY(RegisterLinkedEntities)
 REGISTRY_SORT(LinkedEntities, 0)
+REGISTRY_CHECK(LinkedEntities)
 STATIC_INIT(RegisterLinkedEntities_renumber)
 {
        for (int i = 0; i < LinkedEntities_COUNT; ++i)
@@ -141,6 +142,7 @@ REGISTRY(TempEntities, BITS(8) - 80)
 #define TempEntities_from(i) _TempEntities_from(i, NULL)
 REGISTER_REGISTRY(RegisterTempEntities)
 REGISTRY_SORT(TempEntities, 0)
+REGISTRY_CHECK(TempEntities)
 STATIC_INIT(RegisterTempEntities_renumber)
 {
        for (int i = 0; i < TempEntities_COUNT; ++i)
index eb8372f7638c980791a48179988f8f4f4f6deb3a..59ddf25ff87ee30c627f14fc4cfd25b4ec23b072 100644 (file)
        STATIC_INIT(Registry_sort_##id) \
        { \
                heapsort(id##_COUNT - (skip), _REGISTRY_SWAP_##id, _REGISTRY_CMP_##id, NULL); \
-       } \
-       REGISTRY_CHECK(id)
+       }
+
+#define REGISTRY_HASH(id) Registry_hash_##id
+
+[[accumulate]] void Registry_check(string r, string server) { }
+[[accumulate]] void Registry_send_all() { }
+
+#ifdef SVQC
+void Registry_send(string id, string hash);
+#else
+#define Registry_send(id, hash)
+#endif
 
 #define REGISTRY_CHECK(id) \
+       string REGISTRY_HASH(id); \
        STATIC_INIT(Registry_check_##id) \
        { \
                string algo = "SHA256"; \
                string s = ""; \
                FOREACH(id, true, LAMBDA(s = strcat(s, join, it.registered_id))); \
                s = substring(s, strlen(join), -1); \
-               LOG_TRACEF(#id ": %s\n[%s]\n", digest_hex(algo, s), s); \
-       }
+               string h = REGISTRY_HASH(id) = strzone(digest_hex(algo, s)); \
+               LOG_TRACEF(#id ": %s\n[%s]\n", h, s); \
+       } \
+       [[accumulate]] void Registry_check(string r, string sv) \
+       { \
+               if (r == #id) \
+               { \
+                       string cl = REGISTRY_HASH(id); \
+                       if (cl != sv) \
+                       { \
+                               LOG_FATALF("client/server mismatch (%s).\nCL: %s\nSV: %s\n", r, cl, sv); \
+                       } \
+               } \
+       } \
+       [[accumulate]] void Registry_send_all() { Registry_send(#id, REGISTRY_HASH(id)); } \
 
 #endif
diff --git a/qcsrc/lib/registry_net.qh b/qcsrc/lib/registry_net.qh
new file mode 100644 (file)
index 0000000..14e4dbc
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef REGISTRY_NET_H
+#define REGISTRY_NET_H
+
+#include "net.qh"
+
+REGISTER_NET_TEMP(registry)
+
+#ifdef CSQC
+NET_HANDLE(registry, bool isnew)
+{
+       string k = ReadString();
+       string v = ReadString();
+       Registry_check(k, v);
+       return true;
+}
+#endif
+
+#ifdef SVQC
+void Registry_send(string id, string hash)
+{
+       int channel = MSG_ONE;
+       WriteHeader(channel, registry);
+       WriteString(channel, id);
+       WriteString(channel, hash);
+}
+#endif
+
+#endif
index a604055b8d8ce1a11dd66f3c2246f434fde7aa93..4994c193652cd65b8266ae53c6262768bf669773 100644 (file)
@@ -630,36 +630,40 @@ void PutClientInServer()
 // changes and just have a console command to update this?
 bool ClientInit_SendEntity(entity this, entity to, int sf)
 {
-       WriteHeader(MSG_ENTITY, ENT_CLIENT_INIT);
-       WriteByte(MSG_ENTITY, g_nexball_meter_period * 32);
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[0]));
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[1]));
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[2]));
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[3]));
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[0]));
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[1]));
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[2]));
-       WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[3]));
+       WriteHeader(MSG_ENTITY, _ENT_CLIENT_INIT);
+       return = true;
+       msg_entity = to;
+       Registry_send_all();
+       int channel = MSG_ONE;
+       WriteHeader(channel, ENT_CLIENT_INIT);
+       WriteByte(channel, g_nexball_meter_period * 32);
+       WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[0]));
+       WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[1]));
+       WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[2]));
+       WriteInt24_t(channel, compressShotOrigin(hook_shotorigin[3]));
+       WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[0]));
+       WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[1]));
+       WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[2]));
+       WriteInt24_t(channel, compressShotOrigin(arc_shotorigin[3]));
 
        if(sv_foginterval && world.fog != "")
-               WriteString(MSG_ENTITY, world.fog);
+               WriteString(channel, world.fog);
        else
-               WriteString(MSG_ENTITY, "");
-       WriteByte(MSG_ENTITY, self.count * 255.0); // g_balance_armor_blockpercent
-       WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_mortar_bouncefactor // WEAPONTODO
-       WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_mortar_bouncestop
-       WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_mortar_bouncefactor
-       WriteCoord(MSG_ENTITY, self.ebouncestop); // g_balance_mortar_bouncestop
-       WriteByte(MSG_ENTITY, WEP_CVAR(vortex, secondary)); // client has to know if it should zoom or not // WEAPONTODO
-       WriteByte(MSG_ENTITY, WEP_CVAR(rifle, secondary)); // client has to know if it should zoom or not // WEAPONTODO
-       WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
-       WriteByte(MSG_ENTITY, WEP_CVAR(minelayer, limit)); // minelayer max mines // WEAPONTODO
-       WriteByte(MSG_ENTITY, WEP_CVAR_SEC(hagar, load_max)); // hagar max loadable rockets // WEAPONTODO
-       WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
-       WriteByte(MSG_ENTITY, WEP_CVAR(porto, secondary)); // WEAPONTODO
+               WriteString(channel, "");
+       WriteByte(channel, self.count * 255.0); // g_balance_armor_blockpercent
+       WriteCoord(channel, self.bouncefactor); // g_balance_mortar_bouncefactor // WEAPONTODO
+       WriteCoord(channel, self.bouncestop); // g_balance_mortar_bouncestop
+       WriteCoord(channel, self.ebouncefactor); // g_balance_mortar_bouncefactor
+       WriteCoord(channel, self.ebouncestop); // g_balance_mortar_bouncestop
+       WriteByte(channel, WEP_CVAR(vortex, secondary)); // client has to know if it should zoom or not // WEAPONTODO
+       WriteByte(channel, WEP_CVAR(rifle, secondary)); // client has to know if it should zoom or not // WEAPONTODO
+       WriteByte(channel, serverflags); // client has to know if it should zoom or not
+       WriteByte(channel, WEP_CVAR(minelayer, limit)); // minelayer max mines // WEAPONTODO
+       WriteByte(channel, WEP_CVAR_SEC(hagar, load_max)); // hagar max loadable rockets // WEAPONTODO
+       WriteCoord(channel, autocvar_g_trueaim_minrange);
+       WriteByte(channel, WEP_CVAR(porto, secondary)); // WEAPONTODO
 
        MUTATOR_CALLHOOK(Ent_Init);
-       return true;
 }
 
 void ClientInit_CheckUpdate()