Technical support > Feature Requests

Village mission crash (now with patch)

<< < (3/3)

ubequitz:
Well I thought I had a fix for this bug. It was going to be very simple.

In CL_Precache_f [client/cl_main.c] I tried commenting out the call to CM_LoadMap. I didn't think it was needed since SV_SpawnServer [server/sv_init.c] calls it first so we avoid loading things twice. It also avoids the bug where we free memory that the server has a pointer to (see the earlier postings I made).

However in a Multiplayer game both calls to CM_LoadMap are needed (one for the server and one for the client).

So the fix should be... in CL_Precache_f test to see if the server has loaded the map already and if has, don't load it. I'm not yet sure of a clean way of implementing this test though.

ubequitz:
Here is a patch that corrects the problem. It isn't as absolutely clean as I would have hoped but I've tested it relatively thoroughly and it works.


--- Code: ---
Index: src/qcommon/cmodel.c
===================================================================
--- src/qcommon/cmodel.c        (revision 3093)
+++ src/qcommon/cmodel.c        (working copy)
@@ -176,6 +176,8 @@
 static byte tfList[HEIGHT][WIDTH][WIDTH];
 static byte tf;

+static qboolean mapLoadedByServer = qfalse;
+
 void CM_MakeTnodes(void);
 void CM_InitBoxHull(void);

@@ -1092,7 +1104,7 @@
  * @brief Loads in the map and all submodels
  * @sa CM_AddMapTile
  */
-void CM_LoadMap(char *tiles, char *pos)
+void CM_LoadMap(char *tiles, char *pos, qboolean serverCall)
 {
        char *token;
        char name[MAX_VAR];
@@ -1100,6 +1112,14 @@
        int sh[3];
        int i;

+        /* return if the server has already loaded the map */
+        if (mapLoadedByServer && !serverCall) {
+               mapLoadedByServer = qfalse;
+               return;
+        }
+
+        mapLoadedByServer = serverCall;
+
        /* free old stuff */
        for (i = 0; i < numTiles; i++)
                CM_FreeTile(&mapTiles[i]);
Index: src/qcommon/cmodel.h
===================================================================
--- src/qcommon/cmodel.h        (revision 3093)
+++ src/qcommon/cmodel.h        (working copy)
@@ -11,7 +11,7 @@

 extern vec3_t map_min, map_max;

-void CM_LoadMap(char *tiles, char *pos);
+void CM_LoadMap(char *tiles, char *pos, qboolean serverCall);
 int CheckBSPFile(char *filename);
 cmodel_t *CM_InlineModel(char *name);  /* *0, *1, *2, etc */

Index: src/server/sv_init.c
===================================================================
--- src/server/sv_init.c        (revision 3093)
+++ src/server/sv_init.c        (working copy)
@@ -769,7 +769,7 @@
                else
                        sv.configstrings[CS_POSITIONS][0] = 0;

-               CM_LoadMap(map, pos);
+               CM_LoadMap(map, pos, qtrue);
        } else {
                /* fix this! what here? */
        }
Index: src/client/cl_main.c
===================================================================
--- src/client/cl_main.c        (revision 3093)
+++ src/client/cl_main.c        (working copy)
@@ -980,7 +980,7 @@
        S_StopAllSounds();
        MN_PopMenu(qtrue);

-       CM_LoadMap(cl.configstrings[CS_TILES], cl.configstrings[CS_POSITIONS]);
+       CM_LoadMap(cl.configstrings[CS_TILES], cl.configstrings[CS_POSITIONS], qfalse);

        Com_Printf("LoadMap\n");
        CL_RegisterSounds();

--- End code ---


Basically, CM_LoadMap is only called in two places (once when the server loads a mission map and sometimes by the client). So this patch simply checks to see if the last call to CM_LoadMap was by the server, if it was it doesn't load the map. Otherwise it does (thus if server doesn't load the map - i.e. in multiplayer when you are running the client only, then you still get the map).

PS: I hope this applies ok. In some of those files I have some printf style debugs around the place in my working copy so the line numbers might be slightly out compared to SVN.

Navigation

[0] Message Index

[*] Previous page

Go to full version