@@ -153,7 +153,7 @@ static bool savePacket(RRpacket *p, FILE *f);
153
153
static RRpacket *loadPacket (FILE *f); // makes a new packet
154
154
155
155
static bool saveHeader (int playerIndex, RRtime filetime, FILE *f);
156
- static bool loadHeader (ReplayHeader *h, FILE *f);
156
+ static bool loadHeader (ReplayHeader *h, FILE *f, bool *incompatible );
157
157
static bool saveFileTime (RRtime filetime, FILE *f);
158
158
static bool loadFileTime (RRtime *filetime, FILE *f);
159
159
static bool replaceFlagTypes (ReplayHeader *h);
@@ -759,7 +759,8 @@ bool Replay::loadFile(int playerIndex, const char *filename)
759
759
return false ;
760
760
}
761
761
762
- if (!loadHeader (&header, ReplayFile))
762
+ bool incompatible = false ;
763
+ if (!loadHeader (&header, ReplayFile, &incompatible))
763
764
{
764
765
snprintf (buffer, MessageLen, " Could not open header: %s" , name.c_str ());
765
766
sendMessage (ServerPlayer, playerIndex, buffer);
@@ -832,6 +833,71 @@ bool Replay::loadFile(int playerIndex, const char *filename)
832
833
snprintf (buffer, MessageLen, " end: %s" , ctime (&endTime));
833
834
sendMessage (ServerPlayer, playerIndex, buffer);
834
835
836
+ // If this is an incompatible replay, kick all the viewers
837
+ if (incompatible)
838
+ {
839
+ /* FIXME -- having to rejoin when replay files are loaded
840
+ *
841
+ * Ok, this is where it gets a bit borked. The bzflag client
842
+ * has dynamic arrays for some of its objects (players, flags,
843
+ * shots, etc...) If the client array is too small, there will
844
+ * be memory overruns. The maxPlayers problem is already dealt
845
+ * with, because it is set to (MaxPlayers + ReplayObservers)
846
+ * as soon as the -replay flag is used. The rest of them are
847
+ * still an issue.
848
+ *
849
+ * Here are a few of options:
850
+ *
851
+ * 1) make the command line option -replay <filename>, and
852
+ * only allow loading of world DB's that match the one
853
+ * from the command line file. This is probably how this
854
+ * feature will get used for the most part anyways.
855
+ *
856
+ * 2) kick all observers off of the server if an incompatible
857
+ * record file is loaded (with an appropriate warning).
858
+ * then they can reload with the original DB upon rejoining
859
+ * (DB with modified maxPlayers).
860
+ *
861
+ * 3) make fixed sized arrays on the client side
862
+ * (but what if someone really needs 1000 flags?)
863
+ *
864
+ * 4) implement a world reload feature on the client side,
865
+ * so that if the server sends a MsgGetWorld to the client
866
+ * when it isn't expecting one, it reacquires and regenerates
867
+ * its world DB. this would be the slick way to do it.
868
+ *
869
+ * 5) implement a resizing command, but that's icky.
870
+ *
871
+ * 6) leave it be, and let clients fall where they may.
872
+ *
873
+ * 7) MAC: get to the client to use STL, so segv's aren't a problem
874
+ * (and kick 'em anyways, to force a map reload)
875
+ *
876
+ *
877
+ * maxPlayers [from WorldBuilder.cxx]
878
+ * world->players = new RemotePlayer*[world->maxPlayers];
879
+ *
880
+ * maxFlags [from WorldBuilder.cxx]
881
+ * world->flags = new Flag[world->maxFlags];
882
+ * world->flagNodes = new FlagSceneNode*[world->maxFlags];
883
+ * world->flagWarpNodes = new FlagWarpSceneNode*[world->maxFlags];
884
+ *
885
+ * maxShots [from RemotePlayer.cxx]
886
+ * numShots = World::getWorld()->getMaxShots();
887
+ * shots = new RemoteShotPath*[numShots];
888
+ */
889
+
890
+ // Notify the players that they will need to rejoin
891
+ sendMessage (ServerPlayer, AllPlayers,
892
+ " An incompatible recording has been loaded" );
893
+ sendMessage (ServerPlayer, AllPlayers,
894
+ " Please rejoin the replay server" );
895
+
896
+ // Replay player IDs start at MaxPlayers.
897
+ for (int i = MaxPlayers; i < curMaxPlayers; i++)
898
+ removePlayer (i, " /replay load" );
899
+ }
900
+
835
901
return true ;
836
902
}
837
903
@@ -2107,7 +2173,7 @@ static bool saveHeader(int p, RRtime filetime, FILE *f)
2107
2173
}
2108
2174
2109
2175
2110
- static bool loadHeader (ReplayHeader *h, FILE *f)
2176
+ static bool loadHeader (ReplayHeader *h, FILE *f, bool *incompatible )
2111
2177
{
2112
2178
char buffer[ReplayHeaderSize];
2113
2179
const void *buf;
@@ -2154,81 +2220,22 @@ static bool loadHeader(ReplayHeader *h, FILE *f)
2154
2220
ReplayFileStart = ftell (f);
2155
2221
2156
2222
// do the worldDatabase or flagTypes need to be replaced?
2157
- bool replaced = false ;
2158
2223
if (replaceFlagTypes (h))
2159
2224
{
2160
2225
logDebugMessage (1 ," Replay: replaced flags\n " );
2161
- replaced = true ;
2226
+ *incompatible = true ;
2162
2227
}
2163
2228
if (replaceSettings (h))
2164
2229
{
2165
2230
logDebugMessage (1 ," Replay: replaced settings\n " );
2166
- replaced = true ;
2231
+ *incompatible = true ;
2167
2232
}
2168
2233
if (replaceWorldDatabase (h))
2169
2234
{
2170
2235
logDebugMessage (1 ," Replay: replaced world database\n " );
2171
- replaced = true ;
2236
+ *incompatible = true ;
2172
2237
}
2173
2238
2174
- if (replaced)
2175
- {
2176
- sendMessage (ServerPlayer, AllPlayers,
2177
- " An incompatible recording has been loaded" );
2178
- sendMessage (ServerPlayer, AllPlayers,
2179
- " Please rejoin or face the consequences (client crashes)" );
2180
- }
2181
- /* FIXME -- having to rejoin when replay files are loaded
2182
- *
2183
- * Ok, this is where it gets a bit borked. The bzflag client
2184
- * has dynamic arrays for some of its objects (players, flags,
2185
- * shots, etc...) If the client array is too small, there will
2186
- * be memory overruns. The maxPlayers problem is already dealt
2187
- * with, because it is set to (MaxPlayers + ReplayObservers)
2188
- * as soon as the -replay flag is used. The rest of them are
2189
- * still an issue.
2190
- *
2191
- * Here are a few of options:
2192
- *
2193
- * 1) make the command line option -replay <filename>, and
2194
- * only allow loading of world DB's that match the one
2195
- * from the command line file. This is probably how this
2196
- * feature will get used for the most part anyways.
2197
- *
2198
- * 2) kick all observers off of the server if an incompatible
2199
- * record file is loaded (with an appropriate warning).
2200
- * then they can reload with the original DB upon rejoining
2201
- * (DB with modified maxPlayers).
2202
- *
2203
- * 3) make fixed sized arrays on the client side
2204
- * (but what if someone really needs 1000 flags?)
2205
- *
2206
- * 4) implement a world reload feature on the client side,
2207
- * so that if the server sends a MsgGetWorld to the client
2208
- * when it isn't expecting one, it reacquires and regenerates
2209
- * its world DB. this would be the slick way to do it.
2210
- *
2211
- * 5) implement a resizing command, but that's icky.
2212
- *
2213
- * 6) leave it be, and let clients fall where they may.
2214
- *
2215
- * 7) MAC: get to the client to use STL, so segv's aren't a problem
2216
- * (and kick 'em anyways, to force a map reload)
2217
- *
2218
- *
2219
- * maxPlayers [from WorldBuilder.cxx]
2220
- * world->players = new RemotePlayer*[world->maxPlayers];
2221
- *
2222
- * maxFlags [from WorldBuilder.cxx]
2223
- * world->flags = new Flag[world->maxFlags];
2224
- * world->flagNodes = new FlagSceneNode*[world->maxFlags];
2225
- * world->flagWarpNodes = new FlagWarpSceneNode*[world->maxFlags];
2226
- *
2227
- * maxShots [from RemotePlayer.cxx]
2228
- * numShots = World::getWorld()->getMaxShots();
2229
- * shots = new RemoteShotPath*[numShots];
2230
- */
2231
-
2232
2239
return true ;
2233
2240
}
2234
2241
0 commit comments