]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_ccmds.c
sprite: fix misaligned memory access while loading
[xonotic/darkplaces.git] / sv_ccmds.c
index 613ae309475acb20a3fbe15bf22cb0601a98c9ae..a210b1cb2342abd563eb22a2a8241a5f7dc44c70 100644 (file)
@@ -61,9 +61,9 @@ static void SV_Map_f(cmd_state_t *cmd)
        if (gamemode == GAME_DELUXEQUAKE)
                Cvar_Set(&cvars_all, "warpmark", "");
 
-       cls.demonum = -1;               // stop demo loop in case this fails
+       if(host.hook.Disconnect)
+               host.hook.Disconnect(false, NULL);
 
-       CL_Disconnect ();
        SV_Shutdown();
 
        if(svs.maxclients != svs.maxclients_next)
@@ -74,15 +74,11 @@ static void SV_Map_f(cmd_state_t *cmd)
                svs.clients = (client_t *)Mem_Alloc(sv_mempool, sizeof(client_t) * svs.maxclients);
        }
 
-#ifdef CONFIG_MENU
-       // remove menu
-       if (key_dest == key_menu || key_dest == key_menu_grabbed)
-               MR_ToggleMenu(0);
-#endif
-       key_dest = key_game;
+       if(host.hook.ToggleMenu)
+               host.hook.ToggleMenu();
 
        svs.serverflags = 0;                    // haven't completed an episode yet
-       strlcpy(level, Cmd_Argv(cmd, 1), sizeof(level));
+       dp_strlcpy(level, Cmd_Argv(cmd, 1), sizeof(level));
        SV_SpawnServer(level);
 
        if(sv.active && host.hook.ConnectLocal != NULL)
@@ -112,15 +108,11 @@ static void SV_Changelevel_f(cmd_state_t *cmd)
                return;
        }
 
-#ifdef CONFIG_MENU
-       // remove menu
-       if (key_dest == key_menu || key_dest == key_menu_grabbed)
-               MR_ToggleMenu(0);
-#endif
-       key_dest = key_game;
+       if(host.hook.ToggleMenu)
+               host.hook.ToggleMenu();
 
        SV_SaveSpawnparms ();
-       strlcpy(level, Cmd_Argv(cmd, 1), sizeof(level));
+       dp_strlcpy(level, Cmd_Argv(cmd, 1), sizeof(level));
        SV_SpawnServer(level);
        
        if(sv.active && host.hook.ConnectLocal != NULL)
@@ -149,14 +141,10 @@ static void SV_Restart_f(cmd_state_t *cmd)
                return;
        }
 
-#ifdef CONFIG_MENU
-       // remove menu
-       if (key_dest == key_menu || key_dest == key_menu_grabbed)
-               MR_ToggleMenu(0);
-#endif
-       key_dest = key_game;
+       if(host.hook.ToggleMenu)
+               host.hook.ToggleMenu();
 
-       strlcpy(mapname, sv.name, sizeof(mapname));
+       dp_strlcpy(mapname, sv.name, sizeof(mapname));
        SV_SpawnServer(mapname);
        
        if(sv.active && host.hook.ConnectLocal != NULL)
@@ -481,7 +469,7 @@ static void SV_Say(cmd_state_t *cmd, qbool teamonly)
                p2[-1] = 0;
                p2--;
        }
-       strlcat(text, "\n", sizeof(text));
+       dp_strlcat(text, "\n", sizeof(text));
 
        // note: save is not a valid edict if fromServer is true
        save = host_client;
@@ -748,11 +736,12 @@ static void SV_Status_f(cmd_state_t *cmd)
        for (players = 0, i = 0;i < svs.maxclients;i++)
                if (svs.clients[i].active)
                        players++;
+
        print ("host:     %s\n", Cvar_VariableString (&cvars_all, "hostname", CF_SERVER));
-       print ("version:  %s build %s (gamename %s)\n", gamename, buildstring, gamenetworkfiltername);
+       print ("version:  %s\n", engineversion);
        print ("protocol: %i (%s)\n", Protocol_NumberForEnum(sv.protocol), Protocol_NameForEnum(sv.protocol));
        print ("map:      %s\n", sv.name);
-       print ("timing:   %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
+       print ("timing:   %s\n", SV_TimingReport(vabuf, sizeof(vabuf)));
        print ("players:  %i active (%i max)\n\n", players, svs.maxclients);
 
        if (in == 1)
@@ -791,9 +780,9 @@ static void SV_Status_f(cmd_state_t *cmd)
                }
 
                if(sv_status_privacy.integer && cmd->source != src_local && LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP)
-                       strlcpy(ip, client->netconnection ? "hidden" : "botclient", 48);
+                       dp_strlcpy(ip, client->netconnection ? "hidden" : "botclient", 48);
                else
-                       strlcpy(ip, (client->netconnection && *client->netconnection->address) ? client->netconnection->address : "botclient", 48);
+                       dp_strlcpy(ip, (client->netconnection && *client->netconnection->address) ? client->netconnection->address : "botclient", 48);
 
                frags = client->frags;
 
@@ -849,7 +838,7 @@ void SV_Name(int clientnum)
        {
                if (host_client->begun)
                        SV_BroadcastPrintf("\003%s ^7changed name to ^3%s\n", host_client->old_name, host_client->name);
-               strlcpy(host_client->old_name, host_client->name, sizeof(host_client->old_name));
+               dp_strlcpy(host_client->old_name, host_client->name, sizeof(host_client->old_name));
                // send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
                MSG_WriteByte (&sv.reliable_datagram, clientnum);
@@ -878,7 +867,7 @@ static void SV_Name_f(cmd_state_t *cmd)
        else
                newNameSource = Cmd_Args(cmd);
 
-       strlcpy(newName, newNameSource, sizeof(newName));
+       dp_strlcpy(newName, newNameSource, sizeof(newName));
 
        if (cmd->source == src_local)
                return;
@@ -892,7 +881,7 @@ static void SV_Name_f(cmd_state_t *cmd)
        host_client->nametime = host.realtime + max(0.0f, sv_namechangetimer.value);
 
        // point the string back at updateclient->name to keep it safe
-       strlcpy (host_client->name, newName, sizeof (host_client->name));
+       dp_strlcpy (host_client->name, newName, sizeof (host_client->name));
 
        for (i = 0, j = 0;host_client->name[i];i++)
                if (host_client->name[i] != '\r' && host_client->name[i] != '\n')
@@ -1038,6 +1027,7 @@ static void SV_Kick_f(cmd_state_t *cmd)
 {
        const char *who;
        const char *message = NULL;
+       char reason[512];
        client_t *save;
        int i;
        qbool byNumber = false;
@@ -1096,10 +1086,11 @@ static void SV_Kick_f(cmd_state_t *cmd)
                                message++;
                }
                if (message)
-                       SV_ClientPrintf("Kicked by %s: %s\n", who, message);
+                       SV_DropClient (false, va(reason, sizeof(reason), "Kicked by %s: %s", who, message)); // kicked
+                       //SV_ClientPrintf("Kicked by %s: %s\n", who, message);
                else
-                       SV_ClientPrintf("Kicked by %s\n", who);
-               SV_DropClient (false); // kicked
+                       //SV_ClientPrintf("Kicked by %s\n", who);
+                       SV_DropClient (false, va(reason, sizeof(reason), "Kicked by %s", who)); // kicked
        }
 
        host_client = save;
@@ -1148,9 +1139,9 @@ static void SV_Playermodel_f(cmd_state_t *cmd)
                return;
 
        if (Cmd_Argc (cmd) == 2)
-               strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath));
+               dp_strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath));
        else
-               strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath));
+               dp_strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath));
 
        for (i = 0, j = 0;newPath[i];i++)
                if (newPath[i] != '\r' && newPath[i] != '\n')
@@ -1168,11 +1159,11 @@ static void SV_Playermodel_f(cmd_state_t *cmd)
        */
 
        // point the string back at updateclient->name to keep it safe
-       strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel));
+       dp_strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel));
        PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(prog, host_client->playermodel);
        if (strcmp(host_client->old_model, host_client->playermodel))
        {
-               strlcpy(host_client->old_model, host_client->playermodel, sizeof(host_client->old_model));
+               dp_strlcpy(host_client->old_model, host_client->playermodel, sizeof(host_client->old_model));
                /*// send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatepmodel);
                MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
@@ -1195,9 +1186,9 @@ static void SV_Playerskin_f(cmd_state_t *cmd)
                return;
 
        if (Cmd_Argc (cmd) == 2)
-               strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath));
+               dp_strlcpy (newPath, Cmd_Argv(cmd, 1), sizeof (newPath));
        else
-               strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath));
+               dp_strlcpy (newPath, Cmd_Args(cmd), sizeof (newPath));
 
        for (i = 0, j = 0;newPath[i];i++)
                if (newPath[i] != '\r' && newPath[i] != '\n')
@@ -1215,13 +1206,13 @@ static void SV_Playerskin_f(cmd_state_t *cmd)
        */
 
        // point the string back at updateclient->name to keep it safe
-       strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin));
+       dp_strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin));
        PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(prog, host_client->playerskin);
        if (strcmp(host_client->old_skin, host_client->playerskin))
        {
                //if (host_client->begun)
                //      SV_BroadcastPrintf("%s changed skin to %s\n", host_client->name, host_client->playerskin);
-               strlcpy(host_client->old_skin, host_client->playerskin, sizeof(host_client->old_skin));
+               dp_strlcpy(host_client->old_skin, host_client->playerskin, sizeof(host_client->old_skin));
                /*// send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatepskin);
                MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
@@ -1423,7 +1414,6 @@ static void SV_Ent_Create_f(cmd_state_t *cmd)
        int i;
        qbool haveorigin;
 
-       qbool expectval = false;
        void (*print)(const char *, ...) = (cmd->source == src_client ? SV_ClientPrintf : Con_Printf);
 
        if(!Cmd_Argc(cmd))
@@ -1462,31 +1452,24 @@ static void SV_Ent_Create_f(cmd_state_t *cmd)
        }
 
        // Allow more than one key/value pair by cycling between expecting either one.
-       for(i = 2; i < Cmd_Argc(cmd); i++)
+       for(i = 2; i < Cmd_Argc(cmd); i += 2)
        {
-               if(!expectval)
+               if(!(key = PRVM_ED_FindField(prog, Cmd_Argv(cmd, i))))
                {
-                       if(!(key = PRVM_ED_FindField(prog, Cmd_Argv(cmd, i))))
-                       {
-                               print("Key %s not found!\n", Cmd_Argv(cmd, i));
-                               PRVM_ED_Free(prog, ed);
-                               return;
-                       }
+                       print("Key %s not found!\n", Cmd_Argv(cmd, i));
+                       PRVM_ED_Free(prog, ed);
+                       return;
+               }
 
-                       /*
-                        * This is mostly for dedicated server console, but if the
-                        * player gave a custom origin, we can ignore the traceline.
-                        */
-                       if(!strcmp(Cmd_Argv(cmd, i), "origin"))
-                               haveorigin = true;
+               /*
+                * This is mostly for dedicated server console, but if the
+                * player gave a custom origin, we can ignore the traceline.
+                */
+               if(!strcmp(Cmd_Argv(cmd, i), "origin"))
+                       haveorigin = true;
 
-                       expectval = true;
-               }
-               else
-               {
-                       PRVM_ED_ParseEpair(prog, ed, key, Cmd_Argv(cmd, i), false);
-                       expectval = false;
-               }
+               if (i + 1 < Cmd_Argc(cmd))
+                       PRVM_ED_ParseEpair(prog, ed, key, Cmd_Argv(cmd, i+1), false);
        }
 
        if(!haveorigin)
@@ -1521,7 +1504,7 @@ static void SV_Ent_Remove_f(cmd_state_t *cmd)
 {
        prvm_prog_t *prog = SVVM_prog;
        prvm_edict_t *ed;
-       int i, ednum;
+       int i, ednum = 0;
        void (*print)(const char *, ...) = (cmd->source == src_client ? SV_ClientPrintf : Con_Printf);
 
        if(!Cmd_Argc(cmd))
@@ -1576,7 +1559,7 @@ static void SV_Ent_Remove_f(cmd_state_t *cmd)
                                return;
                }
 
-               if(!ed->priv.required->free)
+               if(!ed->free)
                {
                        print("Removed a \"%s\"\n", PRVM_GetString(prog, PRVM_serveredictstring(ed, classname)));
                        PRVM_ED_ClearEdict(prog, ed);
@@ -1600,7 +1583,7 @@ static void SV_Ent_Remove_All_f(cmd_state_t *cmd)
 
        for (i = 0, rmcount = 0, ed = PRVM_EDICT_NUM(i); i < prog->num_edicts; i++, ed = PRVM_NEXT_EDICT(ed))
        {
-               if(!ed->priv.required->free && !strcmp(PRVM_GetString(prog, PRVM_serveredictstring(ed, classname)), Cmd_Argv(cmd, 1)))
+               if(!ed->free && !strcmp(PRVM_GetString(prog, PRVM_serveredictstring(ed, classname)), Cmd_Argv(cmd, 1)))
                {
                        if(!i)
                        {
@@ -1645,9 +1628,9 @@ void SV_InitOperatorCommands(void)
        Cmd_AddCommand(CF_SHARED, "viewnext", SV_Viewnext_f, "change to next animation frame of viewthing entity in current level");
        Cmd_AddCommand(CF_SHARED, "viewprev", SV_Viewprev_f, "change to previous animation frame of viewthing entity in current level");
        Cmd_AddCommand(CF_SHARED, "maxplayers", SV_MaxPlayers_f, "sets limit on how many players (or bots) may be connected to the server at once");
-       Cmd_AddCommand(CF_SERVER, "sendcvar", SV_SendCvar_f, "sends the value of a cvar to the server as a sentcvar command, for use by QuakeC");
+       host.hook.SV_SendCvar = SV_SendCvar_f;
 
-       // commands that do not have automatic forwarding from cmd_client, these are internal details of the network protocol and not of interest to users (if they know what they are doing they can still use a generic "cmd prespawn" or similar)
+       // commands that do not have automatic forwarding from cmd_local, these are internal details of the network protocol and not of interest to users (if they know what they are doing they can still use a generic "cmd prespawn" or similar)
        Cmd_AddCommand(CF_SERVER_FROM_CLIENT, "prespawn", SV_PreSpawn_f, "internal use - signon 1 (client acknowledges that server information has been received)");
        Cmd_AddCommand(CF_SERVER_FROM_CLIENT, "spawn", SV_Spawn_f, "internal use - signon 2 (client has sent player information, and is asking server to send scoreboard rankings)");
        Cmd_AddCommand(CF_SERVER_FROM_CLIENT, "begin", SV_Begin_f, "internal use - signon 3 (client asks server to start sending entities, and will go to signon 4 (playing) when the first entity update is received)");