// // P_DoTeamscrambling() // // If a team scramble has been started, scramble one person from the // pre-made scramble array. Said array is created in TeamScramble_OnChange() // void P_DoTeamscrambling(void) { changeteam_union NetPacket; UINT16 usvalue; NetPacket.value.l = NetPacket.value.b = 0; // Only do it if we have enough room in the net buffer to send it. // Otherwise, come back next time and try again. if (sizeof(usvalue) > GetFreeXCmdSize()) return; if (scramblecount < scrambletotal) { if (players[scrambleplayers[scramblecount]].ctfteam != scrambleteams[scramblecount]) { NetPacket.packet.newteam = scrambleteams[scramblecount]; NetPacket.packet.playernum = scrambleplayers[scramblecount]; NetPacket.packet.verification = true; NetPacket.packet.scrambled = true; usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); } scramblecount++; //Increment, and get to the next player when we come back here next time. } else CV_SetValue(&cv_teamscramble, 0); }
// Wrapper for COM_AddCommand commands void COM_Lua_f(void) { char *buf, *p; UINT8 i, flags; UINT16 len; INT32 playernum = consoleplayer; I_Assert(gL != NULL); lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command I_Assert(lua_istable(gL, -1)); // use buf temporarily -- must use lowercased string buf = Z_StrDup(COM_Argv(0)); strlwr(buf); lua_getfield(gL, -1, buf); // push command info table I_Assert(lua_istable(gL, -1)); lua_remove(gL, -2); // pop COM_Command Z_Free(buf); lua_rawgeti(gL, -1, 2); // push flags from command info table if (lua_isboolean(gL, -1)) flags = (lua_toboolean(gL, -1) ? 1 : 0); else flags = (UINT8)lua_tointeger(gL, -1); lua_pop(gL, 1); // pop flags if (flags & 2) // flag 2: splitscreen player command. { if (!splitscreen) { lua_pop(gL, 1); // pop command info table return; // can't execute splitscreen command without player 2! } playernum = secondarydisplayplayer; } if (netgame) { // Send the command through the network UINT8 argc; lua_pop(gL, 1); // pop command info table if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. { CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); return; } if (COM_Argc() > UINT8_MAX) argc = UINT8_MAX; else argc = (UINT8)COM_Argc(); if (argc == UINT8_MAX) len = UINT16_MAX; else len = (argc+1)*256; buf = malloc(len); p = buf; WRITEUINT8(p, argc); for (i = 0; i < argc; i++) WRITESTRINGN(p, COM_Argv(i), 255); if (flags & 2) SendNetXCmd2(XD_LUACMD, buf, p-buf); else SendNetXCmd(XD_LUACMD, buf, p-buf); free(buf); return; } // Do the command locally, NetXCmds don't go through outside of GS_LEVEL || GS_INTERMISSION lua_rawgeti(gL, -1, 1); // push function from command info table I_Assert(lua_isfunction(gL, -1)); lua_remove(gL, -2); // pop command info table LUA_PushUserdata(gL, &players[playernum], META_PLAYER); for (i = 1; i < COM_Argc(); i++) lua_pushstring(gL, COM_Argv(i)); LUA_Call(gL, (int)COM_Argc()); // COM_Argc is 1-based, so this will cover the player we passed too. }
void Got_Luacmd(UINT8 **cp, INT32 playernum) { UINT8 i, argc, flags; char buf[256]; // don't use I_Assert here, goto the deny code below // to clean up and kick people who try nefarious exploits // like sending random junk lua commands to crash the server if (!gL) goto deny; lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command if (!lua_istable(gL, -1)) goto deny; argc = READUINT8(*cp); READSTRINGN(*cp, buf, 255); strlwr(buf); // must lowercase buffer lua_getfield(gL, -1, buf); // push command info table if (!lua_istable(gL, -1)) goto deny; lua_remove(gL, -2); // pop COM_Command lua_rawgeti(gL, -1, 2); // push flags from command info table if (lua_isboolean(gL, -1)) flags = (lua_toboolean(gL, -1) ? 1 : 0); else flags = (UINT8)lua_tointeger(gL, -1); lua_pop(gL, 1); // pop flags // requires server/admin and the player is not one of them if ((flags & 1) && playernum != serverplayer && !IsPlayerAdmin(playernum)) goto deny; lua_rawgeti(gL, -1, 1); // push function from command info table // although honestly this should be true anyway // BUT GODDAMNIT I SAID NO I_ASSERTS SO NO I_ASSERTS IT IS if (!lua_isfunction(gL, -1)) goto deny; lua_remove(gL, -2); // pop command info table LUA_PushUserdata(gL, &players[playernum], META_PLAYER); for (i = 1; i < argc; i++) { READSTRINGN(*cp, buf, 255); lua_pushstring(gL, buf); } LUA_Call(gL, (int)argc); // argc is 1-based, so this will cover the player we passed too. return; deny: //must be hacked/buggy client if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18 lua_settop(gL, 0); // clear stack CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]); if (server) { XBOXSTATIC UINT8 bufn[2]; bufn[0] = (UINT8)playernum; bufn[1] = KICK_MSG_CON_FAIL; SendNetXCmd(XD_KICK, &bufn, 2); } }
// // P_DoAutobalanceTeams() // // Determine if the teams are unbalanced, and if so, move a player to the other team. // static void P_DoAutobalanceTeams(void) { changeteam_union NetPacket; UINT16 usvalue; INT32 i=0; INT32 red=0, blue=0; INT32 redarray[MAXPLAYERS], bluearray[MAXPLAYERS]; INT32 redflagcarrier = 0, blueflagcarrier = 0; INT32 totalred = 0, totalblue = 0; NetPacket.value.l = NetPacket.value.b = 0; memset(redarray, 0, sizeof(redarray)); memset(bluearray, 0, sizeof(bluearray)); // Only do it if we have enough room in the net buffer to send it. // Otherwise, come back next time and try again. if (sizeof(usvalue) > GetFreeXCmdSize()) return; //We have to store the players in an array with the rest of their team. //We can then pick a random player to be forced to change teams. for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && players[i].ctfteam) { if (players[i].ctfteam == 1) { if (!players[i].gotflag) { redarray[red] = i; //store the player's node. red++; } else redflagcarrier++; } else { if (!players[i].gotflag) { bluearray[blue] = i; //store the player's node. blue++; } else blueflagcarrier++; } } } totalred = red + redflagcarrier; totalblue = blue + blueflagcarrier; if ((abs(totalred - totalblue) > cv_autobalance.value)) { if (totalred > totalblue) { i = M_Random() % red; NetPacket.packet.newteam = 2; NetPacket.packet.playernum = redarray[i]; NetPacket.packet.verification = true; NetPacket.packet.autobalance = true; usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); } if (totalblue > totalred) { i = M_Random() % blue; NetPacket.packet.newteam = 1; NetPacket.packet.playernum = bluearray[i]; NetPacket.packet.verification = true; NetPacket.packet.autobalance = true; usvalue = SHORT(NetPacket.value.l|NetPacket.value.b); SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue)); } } }