├── .gitignore ├── LICENSE ├── README.md ├── bin └── codextended.so └── src ├── bg_misc.c ├── bg_pmove.c ├── bg_public.h ├── build.sh ├── build.txt ├── cmd.c ├── codextended.c ├── curl.c ├── cvar.c ├── files.c ├── g_active.c ├── g_spawn.c ├── g_utils.c ├── inc.h ├── init.c ├── librarymodule.c ├── license.txt ├── msg.c ├── net_chan.c ├── pre.c ├── q_math.c ├── scr_fields.c ├── scr_io.c ├── scr_method_entity.c ├── scr_method_player.c ├── scr_mysql.c ├── scr_string.c ├── script.c ├── script.h ├── server.h ├── shared.c ├── shared.h ├── steam.cpp ├── steamwrapper.h ├── stripdebuginfo.sh ├── surfaceflags.h ├── sv_client.c ├── sv_commands.c ├── sv_game.c ├── sv_init.c ├── sv_main.c ├── sv_snapshot.asm ├── sv_snapshot.c ├── sv_world.c ├── symbs.txt ├── unix_net.c ├── util.c ├── util.h ├── webserver.c └── x_clientcmds.c /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Call of Duty Extended [Server] 2 | 3 | Call of Duty Extended Server is a modification of the Call of Duty 1 Linux server. It supports patch 1.1 (with outdated 1.5 support). 4 | 5 | ## Features 6 | 7 | - cracked server with unpure fixes (everyone can join) 8 | - Q3 exploit fixes (msgboom, dirtrav) 9 | - ratelimiting 10 | - a lot of new GSC commands + MySQL support 11 | 12 | ## Setup & more info 13 | 14 | Check the [Wiki](https://github.com/riicchhaarrd/codextended/wiki)! 15 | 16 | Forum: http://xtnded.org 17 | 18 | ## License 19 | 20 | CoDExtended is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 21 | 22 | Thanks to [kungfooman](http://killtube.org) and his [libcod](https://github.com/kungfooman/libcod) project (CoD 2 memory modification). 23 | -------------------------------------------------------------------------------- /bin/codextended.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xtnded/codextended/f7b28c8b8ee4cfb03f8d46d6e1df2efe0380cc1b/bin/codextended.so -------------------------------------------------------------------------------- /src/bg_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "bg_public.h" 19 | 20 | char *eventnames[] = { 21 | "EV_NONE", //0 22 | "EV_FOOTSTEP_RUN_DEFAULT", //1 23 | "EV_FOOTSTEP_RUN_BARK", //2 24 | "EV_FOOTSTEP_RUN_BRICK", //3 25 | "EV_FOOTSTEP_RUN_CARPET", //4 26 | "EV_FOOTSTEP_RUN_CLOTH", //5 27 | "EV_FOOTSTEP_RUN_CONCRETE", //6 28 | "EV_FOOTSTEP_RUN_DIRT", //7 29 | "EV_FOOTSTEP_RUN_FLESH", //8 30 | "EV_FOOTSTEP_RUN_FOLIAGE", //9 31 | "EV_FOOTSTEP_RUN_GLASS", //10 32 | "EV_FOOTSTEP_RUN_GRASS", //11 33 | "EV_FOOTSTEP_RUN_GRAVEL", //12 34 | "EV_FOOTSTEP_RUN_ICE", //13 35 | "EV_FOOTSTEP_RUN_METAL", //14 36 | "EV_FOOTSTEP_RUN_MUD", //15 37 | "EV_FOOTSTEP_RUN_PAPER", //16 38 | "EV_FOOTSTEP_RUN_PLASTER", //17 39 | "EV_FOOTSTEP_RUN_ROCK", //18 40 | "EV_FOOTSTEP_RUN_SAND", //19 41 | "EV_FOOTSTEP_RUN_SNOW", //20 42 | "EV_FOOTSTEP_RUN_WATER", //21 43 | "EV_FOOTSTEP_RUN_WOOD", //22 44 | "EV_FOOTSTEP_RUN_ASPHALT", //23 45 | "EV_FOOTSTEP_WALK_DEFAULT", //24 46 | "EV_FOOTSTEP_WALK_BARK", //25 47 | "EV_FOOTSTEP_WALK_BRICK", //26 48 | "EV_FOOTSTEP_WALK_CARPET", //27 49 | "EV_FOOTSTEP_WALK_CLOTH", //28 50 | "EV_FOOTSTEP_WALK_CONCRETE", //29 51 | "EV_FOOTSTEP_WALK_DIRT", //30 52 | "EV_FOOTSTEP_WALK_FLESH", //31 53 | "EV_FOOTSTEP_WALK_FOLIAGE", //32 54 | "EV_FOOTSTEP_WALK_GLASS", //33 55 | "EV_FOOTSTEP_WALK_GRASS", //34 56 | "EV_FOOTSTEP_WALK_GRAVEL", //35 57 | "EV_FOOTSTEP_WALK_ICE", //36 58 | "EV_FOOTSTEP_WALK_METAL", //37 59 | "EV_FOOTSTEP_WALK_MUD", //38 60 | "EV_FOOTSTEP_WALK_PAPER", //39 61 | "EV_FOOTSTEP_WALK_PLASTER", //40 62 | "EV_FOOTSTEP_WALK_ROCK", //41 63 | "EV_FOOTSTEP_WALK_SAND", //42 64 | "EV_FOOTSTEP_WALK_SNOW", //43 65 | "EV_FOOTSTEP_WALK_WATER", //44 66 | "EV_FOOTSTEP_WALK_WOOD", //45 67 | "EV_FOOTSTEP_WALK_ASPHALT", //46 68 | "EV_FOOTSTEP_PRONE_DEFAULT", //47 69 | "EV_FOOTSTEP_PRONE_BARK", //48 70 | "EV_FOOTSTEP_PRONE_BRICK", //49 71 | "EV_FOOTSTEP_PRONE_CARPET", //50 72 | "EV_FOOTSTEP_PRONE_CLOTH", //51 73 | "EV_FOOTSTEP_PRONE_CONCRETE", //52 74 | "EV_FOOTSTEP_PRONE_DIRT", //53 75 | "EV_FOOTSTEP_PRONE_FLESH", //54 76 | "EV_FOOTSTEP_PRONE_FOLIAGE", //55 77 | "EV_FOOTSTEP_PRONE_GLASS", //56 78 | "EV_FOOTSTEP_PRONE_GRASS", //57 79 | "EV_FOOTSTEP_PRONE_GRAVEL", //58 80 | "EV_FOOTSTEP_PRONE_ICE", //59 81 | "EV_FOOTSTEP_PRONE_METAL", //60 82 | "EV_FOOTSTEP_PRONE_MUD", //61 83 | "EV_FOOTSTEP_PRONE_PAPER", //62 84 | "EV_FOOTSTEP_PRONE_PLASTER", //63 85 | "EV_FOOTSTEP_PRONE_ROCK", //64 86 | "EV_FOOTSTEP_PRONE_SAND", //65 87 | "EV_FOOTSTEP_PRONE_SNOW", //66 88 | "EV_FOOTSTEP_PRONE_WATER", //67 89 | "EV_FOOTSTEP_PRONE_WOOD", //68 90 | "EV_FOOTSTEP_PRONE_ASPHALT", //69 91 | "EV_JUMP_DEFAULT", //70 92 | "EV_JUMP_BARK", //71 93 | "EV_JUMP_BRICK", //72 94 | "EV_JUMP_CARPET", //73 95 | "EV_JUMP_CLOTH", //74 96 | "EV_JUMP_CONCRETE", //75 97 | "EV_JUMP_DIRT", //76 98 | "EV_JUMP_FLESH", //77 99 | "EV_JUMP_FOLIAGE", //78 100 | "EV_JUMP_GLASS", //79 101 | "EV_JUMP_GRASS", //80 102 | "EV_JUMP_GRAVEL", //81 103 | "EV_JUMP_ICE", //82 104 | "EV_JUMP_METAL", //83 105 | "EV_JUMP_MUD", //84 106 | "EV_JUMP_PAPER", //85 107 | "EV_JUMP_PLASTER", //86 108 | "EV_JUMP_ROCK", //87 109 | "EV_JUMP_SAND", //88 110 | "EV_JUMP_SNOW", //89 111 | "EV_JUMP_WATER", //90 112 | "EV_JUMP_WOOD", //91 113 | "EV_JUMP_ASPHALT", //92 114 | "EV_LANDING_DEFAULT", //93 115 | "EV_LANDING_BARK", //94 116 | "EV_LANDING_BRICK", //95 117 | "EV_LANDING_CARPET", //96 118 | "EV_LANDING_CLOTH", //97 119 | "EV_LANDING_CONCRETE", //98 120 | "EV_LANDING_DIRT", //99 121 | "EV_LANDING_FLESH", //100 122 | "EV_LANDING_FOLIAGE", //101 123 | "EV_LANDING_GLASS", //102 124 | "EV_LANDING_GRASS", //103 125 | "EV_LANDING_GRAVEL", //104 126 | "EV_LANDING_ICE", //105 127 | "EV_LANDING_METAL", //106 128 | "EV_LANDING_MUD", //107 129 | "EV_LANDING_PAPER", //108 130 | "EV_LANDING_PLASTER", //109 131 | "EV_LANDING_ROCK", //110 132 | "EV_LANDING_SAND", //111 133 | "EV_LANDING_SNOW", //112 134 | "EV_LANDING_WATER", //113 135 | "EV_LANDING_WOOD", //114 136 | "EV_LANDING_ASPHALT", //115 137 | "EV_LANDING_PAIN_DEFAULT", //116 138 | "EV_LANDING_PAIN_BARK", //117 139 | "EV_LANDING_PAIN_BRICK", //118 140 | "EV_LANDING_PAIN_CARPET", //119 141 | "EV_LANDING_PAIN_CLOTH", //120 142 | "EV_LANDING_PAIN_CONCRETE", //121 143 | "EV_LANDING_PAIN_DIRT", //122 144 | "EV_LANDING_PAIN_FLESH", //123 145 | "EV_LANDING_PAIN_FOLIAGE", //124 146 | "EV_LANDING_PAIN_GLASS", //125 147 | "EV_LANDING_PAIN_GRASS", //126 148 | "EV_LANDING_PAIN_GRAVEL", //127 149 | "EV_LANDING_PAIN_ICE", //128 150 | "EV_LANDING_PAIN_METAL", //129 151 | "EV_LANDING_PAIN_MUD", //130 152 | "EV_LANDING_PAIN_PAPER", //131 153 | "EV_LANDING_PAIN_PLASTER", //132 154 | "EV_LANDING_PAIN_ROCK", //133 155 | "EV_LANDING_PAIN_SAND", //134 156 | "EV_LANDING_PAIN_SNOW", //135 157 | "EV_LANDING_PAIN_WATER", //136 158 | "EV_LANDING_PAIN_WOOD", //137 159 | "EV_LANDING_PAIN_ASPHALT", //138 160 | "EV_FOLIAGE_SOUND", //139 161 | "EV_STANCE_FORCE_STAND", //140 162 | "EV_STANCE_FORCE_CROUCH", //141 163 | "EV_STANCE_FORCE_PRONE", //142 164 | "EV_STEP_VIEW", //143 165 | "EV_WATER_TOUCH", //144 166 | "EV_WATER_LEAVE", //145 167 | "EV_ITEM_PICKUP", //146 168 | "EV_ITEM_PICKUP_QUIET", //147 169 | "EV_AMMO_PICKUP", //148 170 | "EV_NOAMMO", //149 171 | "EV_EMPTYCLIP", //150 172 | "EV_RELOAD", //151 173 | "EV_RELOAD_FROM_EMPTY", //152 174 | "EV_RELOAD_START", //153 175 | "EV_RELOAD_END", //154 176 | "EV_RAISE_WEAPON", //155 177 | "EV_PUTAWAY_WEAPON", //156 178 | "EV_WEAPON_ALT", //157 179 | "EV_PULLBACK_WEAPON", //158 180 | "EV_FIRE_WEAPON", //159 181 | "EV_FIRE_WEAPONB", //160 182 | "EV_FIRE_WEAPON_LASTSHOT", //161 183 | "EV_RECHAMBER_WEAPON", //162 184 | "EV_EJECT_BRASS", //163 185 | "EV_MELEE_SWIPE", //164 186 | "EV_FIRE_MELEE", //165 187 | "EV_MELEE_HIT", //166 188 | "EV_MELEE_MISS", //167 189 | "EV_FIRE_WEAPON_MG42", //168 190 | "EV_FIRE_QUADBARREL_1", //169 191 | "EV_FIRE_QUADBARREL_2", //170 192 | "EV_BULLET_TRACER", //171 193 | "EV_SOUND_ALIAS", //172 194 | "EV_BULLET_HIT_SMALL", //173 195 | "EV_BULLET_HIT_LARGE", //174 196 | "EV_BULLET_HIT_CLIENT_SMALL", //175 197 | "EV_BULLET_HIT_CLIENT_LARGE", //176 198 | "EV_GRENADE_BOUNCE", //177 199 | "EV_GRENADE_EXPLODE", //178 200 | "EV_ROCKET_EXPLODE", //179 201 | "EV_ROCKET_EXPLODE_NOMARKS", //180 202 | "EV_MOLOTOV_EXPLODE", //181 203 | "EV_MOLOTOV_EXPLODE_NOMARKS", //182 204 | "EV_CUSTOM_EXPLODE", //183 205 | "EV_CUSTOM_EXPLODE_NOMARKS", //184 206 | "EV_RAILTRAIL", //185 207 | "EV_BULLET", //186 208 | "EV_PAIN", //187 209 | "EV_CROUCH_PAIN", //188 210 | "EV_DEATH", //189 211 | "EV_DEBUG_LINE", //190 212 | "EV_PLAY_FX", //191 213 | "EV_PLAY_FX_DIR", //192 214 | "EV_PLAY_FX_ON_TAG", //193 215 | "EV_FLAMEBARREL_BOUNCE", //194 216 | "EV_EARTHQUAKE", //195 217 | "EV_DROPWEAPON", //196 218 | "EV_ITEM_RESPAWN", //197 219 | "EV_ITEM_POP", //198 220 | "EV_PLAYER_TELEPORT_IN", //199 221 | "EV_PLAYER_TELEPORT_OUT", //200 222 | "EV_OBITUARY" //201 223 | }; -------------------------------------------------------------------------------- /src/bg_pmove.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "server.h" 19 | #include "bg_public.h" 20 | 21 | #define LOBYTE(x) (*((unsigned char*)&(x))) // low byte 22 | #define LOWORD(x) (*((short*)&(x))) // low word 23 | #define LODWORD(x) (*((int*)&(x))) // low dword 24 | #define HIBYTE(x) (*((unsigned char*)&(x)+1)) 25 | #define HIWORD(x) (*((short*)&(x)+1)) 26 | #define HIDWORD(x) (*((int*)&(x)+1)) 27 | #define BYTEn(x, n) (*((unsigned char*)&(x)+n)) 28 | #define WORDn(x, n) (*((short*)&(x)+n)) 29 | #define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0) 30 | #define BYTE2(x) BYTEn(x, 2) 31 | #define BYTE3(x) BYTEn(x, 3) 32 | #define BYTE4(x) BYTEn(x, 4) 33 | #define BYTE5(x) BYTEn(x, 5) 34 | #define BYTE6(x) BYTEn(x, 6) 35 | #define BYTE7(x) BYTEn(x, 7) 36 | #define BYTE8(x) BYTEn(x, 8) 37 | #define BYTE9(x) BYTEn(x, 9) 38 | #define BYTE10(x) BYTEn(x, 10) 39 | #define BYTE11(x) BYTEn(x, 11) 40 | #define BYTE12(x) BYTEn(x, 12) 41 | #define BYTE13(x) BYTEn(x, 13) 42 | #define BYTE14(x) BYTEn(x, 14) 43 | #define BYTE15(x) BYTEn(x, 15) 44 | #define WORD1(x) WORDn(x, 1) 45 | #define WORD2(x) WORDn(x, 2) // third word of the object, unsigned 46 | #define WORD3(x) WORDn(x, 3) 47 | #define WORD4(x) WORDn(x, 4) 48 | #define WORD5(x) WORDn(x, 5) 49 | #define WORD6(x) WORDn(x, 6) 50 | #define WORD7(x) WORDn(x, 7) 51 | 52 | #define OVERCLIP 1.001 53 | 54 | pmove_t *pm; 55 | 56 | static int (*BG_GetNumWeapons)(); 57 | static int (*BG_GetInfoForWeapon)(int); 58 | static int (*BG_AnimScriptEvent)(playerState_t*,int,int,int); 59 | static void (*PM_AddEvent)(int); 60 | 61 | static void (*PM_SetWeaponReloadAddAmmoDelay)(); 62 | static void (*PM_SetReloadingState2)(); 63 | 64 | #define QUICK_RELOAD_FRACTION 3 65 | 66 | static void PM_Weapon( void ) { 67 | pmove_t *xm = *(pmove_t**)(int)pm; 68 | 69 | int *weaponstate = (int*)((int)xm->ps + 180); 70 | int *weapons = *(int**)((int)xm->ps + 796); 71 | int *weapon = (int*)((int)xm->ps + 176); 72 | int *weaponTime = (int*)((int)xm->ps + 44); 73 | int *weaponDelay = (int*)((int)xm->ps + 48); 74 | int prestate = *weaponstate; 75 | 76 | playerState_t *ps = xm->ps; 77 | 78 | int clientNum = *(int*)((int)ps + 172); 79 | client_t *cl = getclient( clientNum ); 80 | gentity_t *ent = &g_entities[clientNum]; 81 | 82 | gclient_t *gclient = ent->client; 83 | 84 | void (*o)() = (void(*)())GAME("PM_Weapon"); 85 | o(); 86 | 87 | #if 1 88 | if((cl->lastUsercmd.buttons & 0x40) == 0x40) { //usebuttonpressed 89 | if(!xclients[clientNum].sprinting) { 90 | 91 | *(int*)((int)gclient + 180) = WEAPON_RECHAMBERING; 92 | *(int*)((int)gclient + 980) = WEAP_ALTSWITCHFROM; 93 | 94 | *(float*)((int)gclient + 848) = 1.35; //runspeedscale? 95 | //*(int*)((int)gclient + 828) = //prone 96 | //*(int*)((int)gclient + 832) = //crouch; 97 | //*(int*)((int)gclient + 836) = 100;//standing; 98 | xclients[clientNum].sprinting = 1; 99 | return; 100 | } 101 | } else { 102 | if(xclients[clientNum].sprinting) { 103 | *(int*)((int)gclient + 180) = WEAPON_READY; 104 | *(int*)((int)gclient + 980) = WEAP_IDLE; 105 | *(float*)((int)gclient + 848) = 1; //runspeedscale? 106 | xclients[clientNum].sprinting = 0; 107 | 108 | return; 109 | } 110 | } 111 | #endif 112 | 113 | //prob shouldnt include interrupts 114 | if(xclients[clientNum].perks[PERK_QUICK_RELOAD] && (prestate == WEAPON_RELOADING || prestate == WEAPON_RELOAD_END || prestate == WEAPON_RELOAD_START || prestate == WEAPON_RECHAMBERING) && (!*weaponDelay || !*weaponTime)) { 115 | *(int*)((int)gclient + 980) = 17; 116 | } 117 | 118 | /* 119 | client_t *cl = getclient( clientNum ); 120 | 121 | xentity_t *xent = &xentities[clientNum]; 122 | gentity_t *ent = g_entities(clientNum); 123 | gclient_t *gclient = ent->client; 124 | 125 | //if(*(int*)((int)ps + 8680) & 0x20 && cl->lastUsercmd.wbuttons & 0x8) { 126 | if(xent->sprinting) { 127 | *(int*)((int)gclient + 180) = WEAPON_RECHAMBERING; 128 | *(int*)((int)gclient + 980) = WEAP_ALTSWITCHFROM; 129 | 130 | //*(int*)((int)gclient + 828) = //prone 131 | //*(int*)((int)gclient + 832) = //crouch; 132 | //*(int*)((int)gclient + 836) = 100;//standing; 133 | return; 134 | } 135 | 136 | //*(int*)((int)gclient + 836) = 60;//standing; 137 | */ 138 | 139 | } 140 | 141 | static void PM_SetReloadingState() { 142 | pmove_t *xm = *(pmove_t**)(int)pm; 143 | 144 | int clientNum = *(int*)((int)xm->ps + 172); 145 | xclient_t *xcl = &xclients[clientNum]; 146 | 147 | int *weaponstate = (int*)((int)xm->ps + 180); 148 | int *weapons = *(int**)((int)xm->ps + 796); 149 | int weapon = *(int*)((int)xm->ps + 176); 150 | int *weaponTime = (int*)((int)xm->ps + 44); 151 | int *weaponDelay = (int*)((int)xm->ps + 48); 152 | 153 | int weaponinfo = BG_GetInfoForWeapon(weapon); 154 | 155 | int v2 = *(int*)((int)pml + 132); 156 | int event = EV_RELOAD_FROM_EMPTY, v3; 157 | if (*(int *)(4 * *(int *)(weaponinfo + 424) + (int)xm->ps + 524) || *(int *)(v2 + 112)) { 158 | if ( xm->ps->pm_type <= 5 ) { 159 | if (xm->cmd.wbuttons ) { 160 | v3 = *(int *)((int)xm->ps + 980) & 0x200; 161 | BYTE1(v3) ^= 2u; 162 | LOBYTE(v3) = 11; 163 | *(int *)((int)xm->ps + 980) = v3; 164 | } 165 | } 166 | if(!xcl->perks[PERK_QUICK_RELOAD]) 167 | *weaponTime = *(int *)(v2 + 488); 168 | else 169 | *weaponTime = (int)(*(int *)(v2 + 488) / QUICK_RELOAD_FRACTION); 170 | event = EV_RELOAD; 171 | } else { 172 | if ( xm->ps->pm_type <= 5 ) { 173 | if (xm->cmd.wbuttons ) { 174 | v3 = *(int *)((int)xm->ps + 980) & 0x200; 175 | BYTE1(v3) ^= 2u; 176 | LOBYTE(v3) = 12; 177 | *(int *)((int)xm->ps + 980) = v3; 178 | } 179 | } 180 | if(!xcl->perks[PERK_QUICK_RELOAD]) 181 | *weaponTime = *(int *)(v2 + 492); 182 | else 183 | *weaponTime = (int)(*(int *)(v2 + 492) / QUICK_RELOAD_FRACTION); 184 | } 185 | PM_AddEvent(event); 186 | if ( *weaponstate == 8 ) 187 | *weaponstate = 6; //WEAPON_RELOADING_INTERRUPT?? 188 | else 189 | *weaponstate = 5; //WEAPON_RELOADING 190 | //if(!reloadtime->integer) 191 | PM_SetWeaponReloadAddAmmoDelay(); 192 | if(xcl->perks[PERK_QUICK_RELOAD]) 193 | *weaponDelay = (int)(*weaponDelay / QUICK_RELOAD_FRACTION); 194 | } 195 | 196 | static void PM_BeginWeaponReload() { //works for kar98 sniper? rest not? mmhm 197 | 198 | pmove_t *xm = *(pmove_t**)(int)pm; 199 | 200 | int clientNum = *(int*)((int)xm->ps + 172); 201 | xclient_t *xcl = &xclients[clientNum]; 202 | 203 | int *weapons = *(int**)((int)xm->ps + 796); 204 | int weapon = *(int*)((int)xm->ps + 176); 205 | int *weaponTime = (int*)((int)xm->ps + 44); 206 | int *weaponDelay = (int*)((int)xm->ps + 48); 207 | 208 | int weaponinfo = BG_GetInfoForWeapon(weapon); 209 | 210 | int *weaponstate = (int*)((int)xm->ps + 180); 211 | 212 | if(*weaponstate == WEAPON_READY || *weaponstate == WEAPON_FIRING || *weaponstate == WEAPON_RECHAMBERING) { 213 | int weapon = *(int*)((int)xm->ps + 176); 214 | if(weapon) { 215 | if(weapon <= BG_GetNumWeapons()) { 216 | 217 | int weaponinfo = BG_GetInfoForWeapon(weapon); 218 | 219 | if(!*(int*)(weaponinfo + 724)) 220 | BG_AnimScriptEvent(xm->ps, 10, 0, 1); 221 | 222 | int v2 = *(int*)((int)pml + 132); 223 | 224 | if(*(int*)(v2 + 748) && *(int*)(v2 + 500)) { 225 | if(xm->ps->pm_type <= 5) { 226 | if(*(unsigned char*)((int)xm + 10)) { 227 | int v4 = *(int*)((int)xm->ps + 980) & 0x200; 228 | BYTE1(v4) ^= 2u; 229 | LOBYTE(v4) = 13; 230 | *(int*)((int)xm->ps + 980) = v4; 231 | } 232 | } 233 | if(xcl->perks[PERK_QUICK_RELOAD]) 234 | *weaponTime = (int)(*(int*)(v2 + 500) / QUICK_RELOAD_FRACTION); 235 | else 236 | *weaponTime = *(int*)(v2 + 500); 237 | *weaponstate = WEAPON_RELOAD_START; //7 238 | 239 | PM_AddEvent(EV_RELOAD_START); 240 | PM_SetWeaponReloadAddAmmoDelay();//sub_377B8 241 | if(xcl->perks[PERK_QUICK_RELOAD]) 242 | *weaponDelay = (int)(*weaponDelay / QUICK_RELOAD_FRACTION); 243 | } else { 244 | PM_SetReloadingState();//sub_378BC 245 | } 246 | } 247 | } 248 | } 249 | } 250 | 251 | static int PM_CheckJump() { 252 | pmove_t *xm = *(pmove_t**)(int)pm; 253 | #if 0 254 | if(xm->cmd.wbuttons & WBUTTON_RELOAD) { 255 | 256 | return 0; 257 | 258 | } 259 | #endif 260 | 261 | int (*cj)() = (int(*)())GAME("BG_PlayerTouchesItem") + 0x7DC; 262 | return cj(); 263 | } 264 | 265 | static int PM_Weapon_CheckForRechamber(int time) { 266 | return 0; 267 | #define int_ptr_val(x) (*(int*)((int)x)) 268 | pmove_t *xm = *(pmove_t**)(int)pm; 269 | 270 | #define ps_off(type, off) (*(type*)((int)xm->ps + off)) 271 | 272 | int *weaponstate = (int*)((int)xm->ps + 180); 273 | int *weapons = *(int**)((int)xm->ps + 796); 274 | int weapon = *(int*)((int)xm->ps + 176); 275 | int *weaponTime = (int*)((int)xm->ps + 44); 276 | int *weaponDelay = (int*)((int)xm->ps + 48); 277 | 278 | int v2 = *(int*)((int)pml + 132); 279 | 280 | if(!int_ptr_val(v2 + 712)) 281 | return 0; 282 | 283 | if(!COM_BitCheck(weapons, weapon)) 284 | return 0; 285 | 286 | if(*weaponstate == WEAPON_RECHAMBERING) { 287 | if(time) { 288 | COM_BitClear(weapons, weapon); 289 | PM_AddEvent(EV_EJECT_BRASS); 290 | if(*weaponTime) 291 | return 1; 292 | } 293 | } 294 | 295 | if(!*weaponTime || ((*weaponstate - WEAPON_FIRING) > WEAPON_RAISING && *weaponstate != WEAPON_MELEE_WINDUP && *weaponstate != WEAPON_MELEE_RELAX && !*weaponDelay)) { 296 | if(*weaponstate == WEAPON_RECHAMBERING) { 297 | if(xm->cmd.wbuttons) { 298 | int *v9 = (int*)((int)xm->ps + 980); 299 | if(*v9 & 0xFFFFFDFF) { 300 | if(xm->ps->pm_type <= 5) { 301 | int v6 = *v9 & 0x200; 302 | BYTE1(v6) ^= 2; 303 | *v9 = v6; 304 | } 305 | } 306 | } 307 | *weaponstate = WEAPON_READY; 308 | return 0; 309 | } 310 | } 311 | 312 | if(*weaponstate == WEAPON_READY) { 313 | if(xm->ps->pm_type > 5 || !xm->cmd.wbuttons) 314 | goto label_27; 315 | /* 316 | 317 | v8 = 0.75 < *(float *)(v2 + 184); 318 | v9 = 0; 319 | v10 = 0.75 == *(float *)(v2 + 184); 320 | if ( (HIBYTE(v7) & 0x45) == 1 ) 321 | { 322 | if ( *(_DWORD *)(v2 + 4) > 5 || !*(_BYTE *)(xm + 10) ) 323 | goto LABEL_27; 324 | v11 = *(_DWORD *)(v2 + 980) & 0x200; 325 | BYTE1(v11) ^= 2u; 326 | LOBYTE(v11) = 7; 327 | } 328 | else 329 | { 330 | if ( *(_DWORD *)(v2 + 4) > 5 || !*(_BYTE *)(xm + 10) ) 331 | goto LABEL_27; 332 | v11 = *(_DWORD *)(v2 + 980) & 0x200; 333 | BYTE1(v11) ^= 2u; 334 | LOBYTE(v11) = 4; 335 | } 336 | *(_DWORD *)(v2 + 980) = v11; 337 | */ 338 | //set cool stuff for keys? 339 | //ps_off(int,980) = 340 | label_27: 341 | *weaponstate = WEAPON_RECHAMBERING; 342 | *weaponTime = int_ptr_val(v2 + 472); 343 | 344 | int v13 = int_ptr_val(v2 + 476); 345 | /* 346 | if(v13 && v13 < *weaponTime) 347 | *weaponDelay = v13; 348 | else 349 | *weaponDelay = 1;*/ 350 | PM_AddEvent(EV_RECHAMBER_WEAPON); 351 | } 352 | 353 | return 0; 354 | #undef int_ptr_val 355 | } 356 | 357 | #if 0 358 | 359 | static void PM_Weapon_CheckForReload() { 360 | pmove_t *xm = *(pmove_t**)(int)pm; 361 | 362 | int reloadRequested = xm->cmd.wbuttons & 8; //check for reload pressed 363 | 364 | 365 | 366 | v8 = *(_BYTE *)(xm + 9) & 8; 367 | v0 = 0; 368 | if ( *(_DWORD *)(*(_DWORD *)&pml[132] + 748) ) 369 | { 370 | v2 = *(_DWORD *)xm; 371 | v1 = *(_DWORD *)(*(_DWORD *)xm + 180); 372 | if ( v1 == 7 || v1 == 5 ) 373 | { 374 | if ( *(_BYTE *)(xm + 8) & 1 ) 375 | { 376 | if ( !(*(_BYTE *)(xm + 32) & 1) ) 377 | { 378 | if ( v1 == 7 ) 379 | { 380 | *(_DWORD *)(v2 + 180) = 8; 381 | } 382 | else 383 | { 384 | if ( v1 == 5 ) 385 | *(_DWORD *)(v2 + 180) = 6; 386 | } 387 | } 388 | } 389 | } 390 | } 391 | result = *(_DWORD *)(*(_DWORD *)xm + 180); 392 | if ( result < 1 || result > 2 && (result > 11 || result < 5) ) 393 | { 394 | v6 = *(_DWORD *)(dword_7C91C + 4 * *(_DWORD *)(*(_DWORD *)xm + 176)); 395 | v4 = *(_DWORD *)(v6 + 424); 396 | v5 = *(_DWORD *)(v6 + 416); 397 | if ( v8 ) 398 | { 399 | if ( sub_3803C() ) 400 | v0 = 1; 401 | } 402 | v7 = *(_DWORD *)xm; 403 | result = *(_DWORD *)xm + 524; 404 | if ( !*(_DWORD *)(result + 4 * v4) ) 405 | { 406 | result = v7 + 268; 407 | if ( *(_DWORD *)(v7 + 268 + 4 * v5) ) 408 | { 409 | if ( *(_DWORD *)(v7 + 180) != 3 ) 410 | { 411 | if ( !(*(_BYTE *)(v7 + 12) & 1) || !*(_WORD *)(xm + 24) ) 412 | v0 = 1; 413 | } 414 | } 415 | } 416 | if ( v0 ) 417 | result = PM_BeginWeaponReload(); 418 | } 419 | return result; 420 | } 421 | 422 | #endif //decided not to do cuz i dont need 423 | 424 | /* 425 | ================== 426 | PM_ClipVelocity 427 | 428 | Slide off of the impacting surface 429 | ================== 430 | */ 431 | void PM_ClipVelocity( vec3_t in, vec3_t normal, vec3_t out, float overbounce ) { 432 | float backoff; 433 | float change; 434 | int i; 435 | 436 | backoff = DotProduct (in, normal); 437 | 438 | if ( backoff < 0 ) { 439 | backoff *= overbounce; 440 | } else { 441 | backoff /= overbounce; 442 | } 443 | 444 | for ( i=0 ; i<3 ; i++ ) { 445 | change = normal[i]*backoff; 446 | out[i] = in[i] - change; 447 | } 448 | } 449 | 450 | #ifdef xDEBUG 451 | void __dump_events() { 452 | char **events = (char**)GAME("eventnames"); 453 | FILE *fp = fopen("/home/rawcod/event.dump", "w"); 454 | if(!fp) 455 | return 0; 456 | int i ; 457 | for( i = 0; i < EV_MAX_EVENTS; i ++) { 458 | fprintf(fp, "\"%s\", //%d\n", events[i], i); 459 | fflush(fp); 460 | } 461 | fclose(fp); 462 | } 463 | #endif 464 | 465 | cvar_t *x_cl_adsair; 466 | 467 | void _PM_ClearAimDownSightFlag() { 468 | /* 469 | qpmove_t *pp = (qpmove_t*)pm; 470 | qps *ps = pp->ps; 471 | 472 | ps->pm_flags &= 0xDFu; 473 | */ 474 | if(!x_cl_adsair->integer) 475 | ((void(*)())GAME("PM_ClearAimDownSightFlag"))(); 476 | } 477 | 478 | void _PM_UpdateAimDownSightFlag() { 479 | #if 0 480 | void (*_BG_UpdateConditionValue)(int,int,int,qboolean); 481 | *(int*)&_BG_UpdateConditionValue = GAME("BG_UpdateConditionValue"); 482 | 483 | qpmove_t *pp = (qpmove_t*)pm; 484 | qps *ps = pp->ps; 485 | 486 | int v3 = *(int*)(&ps->cmdtime + 180); 487 | 488 | //something = *(int *)( *(int *)&pml[132] + 716) 489 | 490 | if(ps->pm_type <= 5 && pp->cmd.buttons & 0x10 && /*&& something*/v3 != 2 && v3 != 1 && v3 != 10 && v3 != 11 /*&& (*(int *)&pml[48] || pm_type == 1) )*/) { 491 | if(ps->pm_flags & 1) { 492 | if(!pp->oldcmd.flags & 0x10 || !pp->oldcmd.serverTime) { 493 | ps->pm_flags |= 0x20; 494 | *(byte*)&ps->pm_flags |= 4; 495 | } 496 | } else { 497 | ps->pm_flags |= 0x20; 498 | } 499 | } else { 500 | ps->pm_flags &= 0xDFu; 501 | } 502 | 503 | //for animations 504 | if ( ps->pm_flags & 0x20 ) 505 | _BG_UpdateConditionValue(*(int*)(ps + 172), 7, 1, 1); 506 | else 507 | _BG_UpdateConditionValue(*(int*)(ps + 172), 7, 0, 1); 508 | #endif 509 | 510 | int *pp = (int*)pm; 511 | int *ps = *pp; 512 | int *gclient = *ps; 513 | 514 | int *v4 = (int *)(ps + 12); 515 | 516 | int val = *(int*)(gclient + 21); //336? 84*4=336 /84/4=21?? 517 | 518 | //Com_DPrintf("val = %d\n", val); 519 | 520 | if (val == 1023 && x_cl_adsair->integer) { 521 | *v4 |= 0x20; 522 | return; 523 | } 524 | 525 | void (*call)(); 526 | *(int*)&call=GAME("PM_UpdateAimDownSightFlag"); 527 | call(); 528 | } 529 | 530 | void BG_Link() { 531 | return; //experimental stuff and most people wont need this 532 | #ifdef xDEBUG 533 | Cmd_AddCommand("debug_dumpevents", __dump_events); 534 | #endif 535 | 536 | BG_GetNumWeapons = (int(*)())GAME("BG_GetNumWeapons"); 537 | BG_GetInfoForWeapon = (int(*)(int))GAME("BG_GetInfoForWeapon"); 538 | BG_AnimScriptEvent = (int(*)(playerState_t*,int,int,int))GAME("BG_AnimScriptEvent"); 539 | PM_AddEvent = (void(*)(int))GAME("PM_AddEvent"); 540 | 541 | //sub_37488 542 | //GAME("PM_InteruptWeaponWithProneMove"); 543 | 544 | PM_SetReloadingState2 = (void(*)())GAME("PM_InteruptWeaponWithProneMove") + 0x434; 545 | PM_SetWeaponReloadAddAmmoDelay = (void(*)())GAME("PM_InteruptWeaponWithProneMove") + 0x330; 546 | 547 | #ifdef xDEBUG 548 | __jmp(GAME("PM_InteruptWeaponWithProneMove") + 0x434, (int)PM_SetReloadingState); 549 | __jmp(GAME("PM_InteruptWeaponWithProneMove") + 0x530, (int)PM_BeginWeaponReload); 550 | //__jmp(GAME("PM_InteruptWeaponWithProneMove") + 0x148, (int)PM_Weapon_CheckForRechamber); 551 | 552 | __call(GAME("PmoveSingle")+0x455, (int)PM_Weapon); 553 | __call(GAME("PmoveSingle")+0x535, (int)PM_Weapon); 554 | 555 | __call(GAME("BG_PlayerTouchesItem") + 0xEA5, (int)PM_CheckJump); 556 | #endif 557 | /* 558 | aim in air if client allows it 559 | maybe add a groundEntityNum = 1023; force??? 560 | - Richard 561 | */ 562 | //__jmp( dlsym(gamelib, "PM_UpdateAimDownSightFlag"), _PM_UpdateAimDownSightFlag); 563 | int thk = GAME("PmoveSingle"); 564 | __call(thk + 0x3cc, _PM_UpdateAimDownSightFlag); 565 | __call(thk + 0x3ea, _PM_UpdateAimDownSightFlag); 566 | __call(thk + 0x404, _PM_UpdateAimDownSightFlag); 567 | __call(thk + 0x441, _PM_UpdateAimDownSightFlag); 568 | __call(thk + 0x49e, _PM_UpdateAimDownSightFlag); 569 | __call(thk + 0x4d7, _PM_UpdateAimDownSightFlag); 570 | //__jmp( GAME("PM_ClearAimDownSightFlag"), _PM_ClearAimDownSightFlag); 571 | __call( thk + 0xFD, _PM_ClearAimDownSightFlag); 572 | __call( GAME("vmMain") - 0x1F119, _PM_ClearAimDownSightFlag); 573 | } -------------------------------------------------------------------------------- /src/bg_public.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | #ifndef BG_PUBLIC_H 21 | #define BG_PUBLIC_H 22 | 23 | typedef enum { 24 | EV_NONE, //0 25 | EV_FOOTSTEP_RUN_DEFAULT, //1 26 | EV_FOOTSTEP_RUN_BARK, //2 27 | EV_FOOTSTEP_RUN_BRICK, //3 28 | EV_FOOTSTEP_RUN_CARPET, //4 29 | EV_FOOTSTEP_RUN_CLOTH, //5 30 | EV_FOOTSTEP_RUN_CONCRETE, //6 31 | EV_FOOTSTEP_RUN_DIRT, //7 32 | EV_FOOTSTEP_RUN_FLESH, //8 33 | EV_FOOTSTEP_RUN_FOLIAGE, //9 34 | EV_FOOTSTEP_RUN_GLASS, //10 35 | EV_FOOTSTEP_RUN_GRASS, //11 36 | EV_FOOTSTEP_RUN_GRAVEL, //12 37 | EV_FOOTSTEP_RUN_ICE, //13 38 | EV_FOOTSTEP_RUN_METAL, //14 39 | EV_FOOTSTEP_RUN_MUD, //15 40 | EV_FOOTSTEP_RUN_PAPER, //16 41 | EV_FOOTSTEP_RUN_PLASTER, //17 42 | EV_FOOTSTEP_RUN_ROCK, //18 43 | EV_FOOTSTEP_RUN_SAND, //19 44 | EV_FOOTSTEP_RUN_SNOW, //20 45 | EV_FOOTSTEP_RUN_WATER, //21 46 | EV_FOOTSTEP_RUN_WOOD, //22 47 | EV_FOOTSTEP_RUN_ASPHALT, //23 48 | EV_FOOTSTEP_WALK_DEFAULT, //24 49 | EV_FOOTSTEP_WALK_BARK, //25 50 | EV_FOOTSTEP_WALK_BRICK, //26 51 | EV_FOOTSTEP_WALK_CARPET, //27 52 | EV_FOOTSTEP_WALK_CLOTH, //28 53 | EV_FOOTSTEP_WALK_CONCRETE, //29 54 | EV_FOOTSTEP_WALK_DIRT, //30 55 | EV_FOOTSTEP_WALK_FLESH, //31 56 | EV_FOOTSTEP_WALK_FOLIAGE, //32 57 | EV_FOOTSTEP_WALK_GLASS, //33 58 | EV_FOOTSTEP_WALK_GRASS, //34 59 | EV_FOOTSTEP_WALK_GRAVEL, //35 60 | EV_FOOTSTEP_WALK_ICE, //36 61 | EV_FOOTSTEP_WALK_METAL, //37 62 | EV_FOOTSTEP_WALK_MUD, //38 63 | EV_FOOTSTEP_WALK_PAPER, //39 64 | EV_FOOTSTEP_WALK_PLASTER, //40 65 | EV_FOOTSTEP_WALK_ROCK, //41 66 | EV_FOOTSTEP_WALK_SAND, //42 67 | EV_FOOTSTEP_WALK_SNOW, //43 68 | EV_FOOTSTEP_WALK_WATER, //44 69 | EV_FOOTSTEP_WALK_WOOD, //45 70 | EV_FOOTSTEP_WALK_ASPHALT, //46 71 | EV_FOOTSTEP_PRONE_DEFAULT, //47 72 | EV_FOOTSTEP_PRONE_BARK, //48 73 | EV_FOOTSTEP_PRONE_BRICK, //49 74 | EV_FOOTSTEP_PRONE_CARPET, //50 75 | EV_FOOTSTEP_PRONE_CLOTH, //51 76 | EV_FOOTSTEP_PRONE_CONCRETE, //52 77 | EV_FOOTSTEP_PRONE_DIRT, //53 78 | EV_FOOTSTEP_PRONE_FLESH, //54 79 | EV_FOOTSTEP_PRONE_FOLIAGE, //55 80 | EV_FOOTSTEP_PRONE_GLASS, //56 81 | EV_FOOTSTEP_PRONE_GRASS, //57 82 | EV_FOOTSTEP_PRONE_GRAVEL, //58 83 | EV_FOOTSTEP_PRONE_ICE, //59 84 | EV_FOOTSTEP_PRONE_METAL, //60 85 | EV_FOOTSTEP_PRONE_MUD, //61 86 | EV_FOOTSTEP_PRONE_PAPER, //62 87 | EV_FOOTSTEP_PRONE_PLASTER, //63 88 | EV_FOOTSTEP_PRONE_ROCK, //64 89 | EV_FOOTSTEP_PRONE_SAND, //65 90 | EV_FOOTSTEP_PRONE_SNOW, //66 91 | EV_FOOTSTEP_PRONE_WATER, //67 92 | EV_FOOTSTEP_PRONE_WOOD, //68 93 | EV_FOOTSTEP_PRONE_ASPHALT, //69 94 | EV_JUMP_DEFAULT, //70 95 | EV_JUMP_BARK, //71 96 | EV_JUMP_BRICK, //72 97 | EV_JUMP_CARPET, //73 98 | EV_JUMP_CLOTH, //74 99 | EV_JUMP_CONCRETE, //75 100 | EV_JUMP_DIRT, //76 101 | EV_JUMP_FLESH, //77 102 | EV_JUMP_FOLIAGE, //78 103 | EV_JUMP_GLASS, //79 104 | EV_JUMP_GRASS, //80 105 | EV_JUMP_GRAVEL, //81 106 | EV_JUMP_ICE, //82 107 | EV_JUMP_METAL, //83 108 | EV_JUMP_MUD, //84 109 | EV_JUMP_PAPER, //85 110 | EV_JUMP_PLASTER, //86 111 | EV_JUMP_ROCK, //87 112 | EV_JUMP_SAND, //88 113 | EV_JUMP_SNOW, //89 114 | EV_JUMP_WATER, //90 115 | EV_JUMP_WOOD, //91 116 | EV_JUMP_ASPHALT, //92 117 | EV_LANDING_DEFAULT, //93 118 | EV_LANDING_BARK, //94 119 | EV_LANDING_BRICK, //95 120 | EV_LANDING_CARPET, //96 121 | EV_LANDING_CLOTH, //97 122 | EV_LANDING_CONCRETE, //98 123 | EV_LANDING_DIRT, //99 124 | EV_LANDING_FLESH, //100 125 | EV_LANDING_FOLIAGE, //101 126 | EV_LANDING_GLASS, //102 127 | EV_LANDING_GRASS, //103 128 | EV_LANDING_GRAVEL, //104 129 | EV_LANDING_ICE, //105 130 | EV_LANDING_METAL, //106 131 | EV_LANDING_MUD, //107 132 | EV_LANDING_PAPER, //108 133 | EV_LANDING_PLASTER, //109 134 | EV_LANDING_ROCK, //110 135 | EV_LANDING_SAND, //111 136 | EV_LANDING_SNOW, //112 137 | EV_LANDING_WATER, //113 138 | EV_LANDING_WOOD, //114 139 | EV_LANDING_ASPHALT, //115 140 | EV_LANDING_PAIN_DEFAULT, //116 141 | EV_LANDING_PAIN_BARK, //117 142 | EV_LANDING_PAIN_BRICK, //118 143 | EV_LANDING_PAIN_CARPET, //119 144 | EV_LANDING_PAIN_CLOTH, //120 145 | EV_LANDING_PAIN_CONCRETE, //121 146 | EV_LANDING_PAIN_DIRT, //122 147 | EV_LANDING_PAIN_FLESH, //123 148 | EV_LANDING_PAIN_FOLIAGE, //124 149 | EV_LANDING_PAIN_GLASS, //125 150 | EV_LANDING_PAIN_GRASS, //126 151 | EV_LANDING_PAIN_GRAVEL, //127 152 | EV_LANDING_PAIN_ICE, //128 153 | EV_LANDING_PAIN_METAL, //129 154 | EV_LANDING_PAIN_MUD, //130 155 | EV_LANDING_PAIN_PAPER, //131 156 | EV_LANDING_PAIN_PLASTER, //132 157 | EV_LANDING_PAIN_ROCK, //133 158 | EV_LANDING_PAIN_SAND, //134 159 | EV_LANDING_PAIN_SNOW, //135 160 | EV_LANDING_PAIN_WATER, //136 161 | EV_LANDING_PAIN_WOOD, //137 162 | EV_LANDING_PAIN_ASPHALT, //138 163 | EV_FOLIAGE_SOUND, //139 164 | EV_STANCE_FORCE_STAND, //140 165 | EV_STANCE_FORCE_CROUCH, //141 166 | EV_STANCE_FORCE_PRONE, //142 167 | EV_STEP_VIEW, //143 168 | EV_WATER_TOUCH, //144 169 | EV_WATER_LEAVE, //145 170 | EV_ITEM_PICKUP, //146 171 | EV_ITEM_PICKUP_QUIET, //147 172 | EV_AMMO_PICKUP, //148 173 | EV_NOAMMO, //149 174 | EV_EMPTYCLIP, //150 175 | EV_RELOAD, //151 176 | EV_RELOAD_FROM_EMPTY, //152 177 | EV_RELOAD_START, //153 178 | EV_RELOAD_END, //154 179 | EV_RAISE_WEAPON, //155 180 | EV_PUTAWAY_WEAPON, //156 181 | EV_WEAPON_ALT, //157 182 | EV_PULLBACK_WEAPON, //158 183 | EV_FIRE_WEAPON, //159 184 | EV_FIRE_WEAPONB, //160 185 | EV_FIRE_WEAPON_LASTSHOT, //161 186 | EV_RECHAMBER_WEAPON, //162 187 | EV_EJECT_BRASS, //163 188 | EV_MELEE_SWIPE, //164 189 | EV_FIRE_MELEE, //165 190 | EV_MELEE_HIT, //166 191 | EV_MELEE_MISS, //167 192 | EV_FIRE_WEAPON_MG42, //168 193 | EV_FIRE_QUADBARREL_1, //169 194 | EV_FIRE_QUADBARREL_2, //170 195 | EV_BULLET_TRACER, //171 196 | EV_SOUND_ALIAS, //172 197 | EV_BULLET_HIT_SMALL, //173 198 | EV_BULLET_HIT_LARGE, //174 199 | EV_BULLET_HIT_CLIENT_SMALL, //175 200 | EV_BULLET_HIT_CLIENT_LARGE, //176 201 | EV_GRENADE_BOUNCE, //177 202 | EV_GRENADE_EXPLODE, //178 203 | EV_ROCKET_EXPLODE, //179 204 | EV_ROCKET_EXPLODE_NOMARKS, //180 205 | EV_MOLOTOV_EXPLODE, //181 206 | EV_MOLOTOV_EXPLODE_NOMARKS, //182 207 | EV_CUSTOM_EXPLODE, //183 208 | EV_CUSTOM_EXPLODE_NOMARKS, //184 209 | EV_RAILTRAIL, //185 210 | EV_BULLET, //186 211 | EV_PAIN, //187 212 | EV_CROUCH_PAIN, //188 213 | EV_DEATH, //189 214 | EV_DEBUG_LINE, //190 215 | EV_PLAY_FX, //191 216 | EV_PLAY_FX_DIR, //192 217 | EV_PLAY_FX_ON_TAG, //193 218 | EV_FLAMEBARREL_BOUNCE, //194 219 | EV_EARTHQUAKE, //195 220 | EV_DROPWEAPON, //196 221 | EV_ITEM_RESPAWN, //197 222 | EV_ITEM_POP, //198 223 | EV_PLAYER_TELEPORT_IN, //199 224 | EV_PLAYER_TELEPORT_OUT, //200 225 | EV_OBITUARY, //201 226 | EV_MAX_EVENTS //202 227 | } entity_event_t; 228 | 229 | typedef void (*G_FreeEntity_t)(gentity_t*); 230 | extern G_FreeEntity_t G_FreeEntity; 231 | 232 | typedef gentity_t* (*G_Spawn_t)(); 233 | extern G_Spawn_t G_Spawn; 234 | 235 | typedef void (*G_SetOrigin_t)( gentity_t*, vec3_t); 236 | extern G_SetOrigin_t G_SetOrigin; 237 | 238 | typedef void (*G_SetAngle_t)( gentity_t*, vec3_t); 239 | extern G_SetAngle_t G_SetAngle; 240 | 241 | #endif -------------------------------------------------------------------------------- /src/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cc="gcc -fcommon -include inc.h -I./include" 4 | #LINK_LIBS="$(/usr/bin/curl-config --static-libs --cflags)"; 5 | LINK_LIBS="" 6 | STEAM_INCLUDE="" 7 | STEAM_LINK="" 8 | 9 | info() 10 | { 11 | cat << EOF 12 | CoDExtended 13 | Linux 14 | by 15 | riicchhaarrd 16 | 17 | http://github.com/riicchhaarrd/CoDExtended 18 | http://cod1.eu/ 19 | EOF 20 | } 21 | 22 | PATCHVERSION=1 23 | uSTEAM=false 24 | uANY=false 25 | uMYSQL=false 26 | uFEATUREUNSAFE=false 27 | DEBUG=false 28 | DEFINES="" 29 | 30 | while getopts “hsmdu15” qo 31 | do 32 | case $qo in 33 | h) 34 | info 35 | exit 1 36 | ;; 37 | s) 38 | uSTEAM=true 39 | uANY=true 40 | ;; 41 | m) 42 | uMYSQL=true 43 | uANY=true 44 | ;; 45 | d) 46 | DEBUG=true 47 | ;; 48 | u) 49 | uFEATUREUNSAFE=true 50 | uANY=true 51 | ;; 52 | 1) 53 | PATCHVERSION=1 54 | ;; 55 | 5) 56 | PATCHVERSION=5 57 | ;; 58 | esac 59 | done 60 | 61 | if [ $uSTEAM = true ]; then 62 | STEAM_INCLUDE="-I/home/r/deps/steamsdk/sdk/public" 63 | STEAM_LINK="-L/home/r/deps/steamsdk/sdk/redistributable_bin/linux32 -lsteam_api" 64 | fi 65 | 66 | if [ $PATCHVERSION = 5 ]; then 67 | echo "Call of Duty Patch 1.5" 68 | else 69 | echo "Call of Duty Patch 1.1" 70 | fi 71 | 72 | if [ $DEBUG = true ]; then 73 | echo "{ CODEXTENDED DEVELOPMENT BUILD }" 74 | else 75 | echo "{ CODEXTENDED RELEASE BUILD }" 76 | fi 77 | 78 | if [ $uANY = true ]; then 79 | echo "Using: " 80 | fi 81 | 82 | if [ $uMYSQL = true ]; then 83 | echo -n "MYSQL, " 84 | fi 85 | 86 | if [ $uFEATUREUNSAFE = true ]; then 87 | echo -n "Unsafe features, " 88 | fi 89 | 90 | if [ $uANY = true ]; then 91 | echo "" 92 | fi 93 | 94 | #Compiling CoDExtended 95 | 96 | compiler="$cc -Os -O1 -O3 -s -fvisibility=hidden -w -Wl,--exclude-libs,ALL" 97 | 98 | if [ $DEBUG = true ]; then 99 | compiler="$cc -g -w -Wl,--exclude-libs,ALL" 100 | #compiler="$cc -DxDEBUG -DDEBUG -Os -O1 -O3 -s -fvisibility=hidden -w -Wl,--exclude-libs,ALL" 101 | fi 102 | 103 | if [ $uMYSQL = true ]; then 104 | DEFINES+="-DuMYSQL " 105 | fi 106 | 107 | if [ $uFEATUREUNSAFE = true ]; then 108 | DEFINES+="-DuFEATUREUNSAFE " 109 | fi 110 | 111 | if [ $PATCHVERSION = 5 ]; then 112 | DEFINES+="-DCODPATCH=5 " 113 | else 114 | DEFINES+="-DCODPATCH=1 " 115 | fi 116 | 117 | if [ $uSTEAM = true ]; then 118 | DEFINES+="-DSTEAM_SUPPORT " 119 | fi 120 | 121 | params="$DEFINES -std=c99 -I. -m32 -fPIC -Wno-write-strings" 122 | #params="-m32 -fPIC -Wno-write-strings" 123 | 124 | mkdir -p ../bin 125 | mkdir -p obj 126 | 127 | echo -e "\nCOMPILING" 128 | 129 | #echo "[CPPP]" 130 | #for f in cppp/*.c; do 131 | # filename=$(basename "$f") 132 | # extension="${filename##*.}" 133 | # filename="${filename%.*}" 134 | # $compiler $params -c cppp/$filename.c -o obj/$filename.o 135 | #done 136 | 137 | 138 | echo "[ROOT]" 139 | $compiler $params -c init.c -o obj/init.o 140 | $compiler $params -c librarymodule.c -o obj/librarymodule.o 141 | $compiler $params -c codextended.c -o obj/codextended.o 142 | echo "[COMMON]" 143 | $compiler $params -c cvar.c -o obj/cvar.o 144 | $compiler $params -c cmd.c -o obj/cmd.o 145 | $compiler $params -c msg.c -o obj/msg.o 146 | $compiler $params -c curl.c -o obj/curl.o 147 | $compiler $params -c util.c -o obj/util.o 148 | echo "[GAME]" 149 | $compiler $params -c shared.c -o obj/shared.o 150 | $compiler $params -c script.c -o obj/script.o 151 | $compiler $params -c bg_pmove.c -o obj/bg_pmove.o 152 | $compiler $params -c bg_misc.c -o obj/bg_misc.o 153 | $compiler $params -c g_utils.c -o obj/g_utils.o 154 | $compiler $params -c g_spawn.c -o obj/g_spawn.o 155 | $compiler $params -c g_active.c -o obj/g_active.o 156 | $compiler $params -c q_math.c -o obj/q_math.o 157 | $compiler $params -c files.c -o obj/files.o 158 | echo "[SERVER]" 159 | nasm -f elf sv_snapshot.asm -o obj/sv_snapshot_asm.o 160 | $compiler $params -c sv_snapshot.c -o obj/sv_snapshot.o 161 | $compiler $params -c sv_commands.c -o obj/sv_commands.o 162 | $compiler $params -c sv_client.c -o obj/sv_client.o 163 | $compiler $params -c sv_world.c -o obj/sv_world.o 164 | $compiler $params -c sv_game.c -o obj/sv_game.o 165 | $compiler $params -c sv_init.c -o obj/sv_init.o 166 | $compiler $params -c net_chan.c -o obj/net_chan.o 167 | $compiler $params -c sv_main.c -o obj/sv_main.o 168 | $compiler $params -c x_clientcmds.c -o obj/x_clientcmds.o 169 | $compiler $params -c unix_net.c -o obj/unix_net.o 170 | $compiler $params -c webserver.c -o obj/webserver.o 171 | 172 | if [ $uSTEAM = true ]; then 173 | g++ -include inc.h -Os -O1 -O3 -s -fvisibility=hidden -w -Wl,--exclude-libs,ALL -I. -m32 -fPIC -Wno-write-strings $STEAM_INCLUDE -c steam.cpp -o obj/steam.o 174 | fi 175 | 176 | echo "[SCRIPT]" 177 | $compiler $params -c pre.c -o obj/pre.o 178 | $compiler $params -c scr_method_player.c -o obj/scr_method_player.o 179 | $compiler $params -c scr_string.c -o obj/scr_string.o 180 | $compiler $params -c scr_fields.c -o obj/scr_fields.o 181 | $compiler $params -c scr_method_entity.c -o obj/scr_method_entity.o 182 | 183 | if [ $uMYSQL = true ]; then 184 | $compiler $params -c scr_mysql.c -o obj/scr_mysql.o 185 | fi 186 | 187 | obj="$(ls obj/*.o)" 188 | 189 | #if [ $DEBUG = true ]; then 190 | #for f in obj/*.o; do 191 | #if [ "$f" != "duktape.o" ] && [ "$f" != "steam.o" ]; then 192 | #objcopy --keep-symbols=symbols.txt --prefix-symbols=xtn_ $f 193 | #objcopy --redefine-syms=symbs.txt $f 194 | #objcopy --prefix-symbols=`basename $f .o`_ $f 195 | #objcopy --prefix-symbols=xtn_ $f 196 | #echo "placeholder" > /dev/null 197 | #fi 198 | #done 199 | #fi 200 | 201 | if [ $uMYSQL = true ]; then 202 | if [ $DEBUG = true ]; then 203 | $compiler -m32 -shared -L/lib32 -L/home/lib `mysql_config --libs --include` -o ../bin/codextended.so $obj -Os -lz $LINK_LIBS $STEAM_LINK -ldl -lm -Wall 204 | else 205 | $compiler -m32 -shared -L/lib32 -L/home/lib `mysql_config --libs --include` -o ../bin/codextended.so $obj -Os -s -lz $LINK_LIBS $STEAM_LINK -ldl -lm -Wall 206 | fi 207 | #$compiler -m32 -shared -L/lib32 `mysql_config --libs` `mysql_config --include` -o ../bin/codextended.so $obj -Os -s -lz $LINK_LIBS -ldl -lm -Wall 208 | else 209 | if [ $DEBUG = true ]; then 210 | $compiler -m32 -shared -L/lib32 -L./lib -o ../bin/codextended.so $obj -lz $LINK_LIBS $STEAM_LINK -ldl -lm -Wall 211 | else 212 | $compiler -m32 -shared -L/lib32 -L./lib -o ../bin/codextended.so $obj -Os -s -lz $LINK_LIBS $STEAM_LINK -ldl -lm -Wall 213 | fi 214 | fi 215 | #rm -rf ./obj 216 | find ./obj -name '*.o' ! -name 'duktape.o' -delete 217 | echo "Done." 218 | -------------------------------------------------------------------------------- /src/build.txt: -------------------------------------------------------------------------------- 1 | #define CLIENTBUILD 11 2 | #define SERVERBUILD 20 3 | 4 | #define CLIENT_VERSION CLIENTBUILD 5 | #define CLIENTVERSION CLIENTBUILD 6 | #define CURRENTBUILD SERVERBUILD 7 | #define BUILDNUMBER SERVERBUILD -------------------------------------------------------------------------------- /src/cmd.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | /* 21 | Patches max execute file, just like in patch 1.3 22 | 23 | I quote 24 | 25 | `- Increased the max cfg file that can be executed to 64K from 16K.` 26 | 27 | - Richard 28 | */ 29 | 30 | void Cbuf_Init( void ) { 31 | void (*original)( void ); 32 | *(int*)&original = 0x805B0B4; 33 | 34 | original(); //let's call the original and then modify the limit 35 | 36 | *(int*)0x8329328 = 262144; //changed from 16k to 256k //16384; 37 | } 38 | 39 | typedef struct cmd_function_s 40 | { 41 | struct cmd_function_s *next; 42 | char *name; 43 | xcommand_t function; 44 | } cmd_function_t; 45 | 46 | static cmd_function_t *cmd_functions = (cmd_function_t*)0x810EA20; 47 | 48 | void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) { 49 | cmd_function_t *cmd; 50 | /* 51 | for ( cmd = cmd_functions ; cmd ; cmd = cmd->next ) { 52 | if ( !strcmp( cmd_name, cmd->name ) ) { 53 | if ( function != NULL ) { 54 | cmd->function = function; 55 | } 56 | return; 57 | } 58 | } 59 | */ 60 | 61 | _Cmd_AddCommand(cmd_name, function); 62 | } -------------------------------------------------------------------------------- /src/codextended.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | /* 19 | Call of Duty Extended 20 | by riicchhaarrd 21 | 22 | http://github.com/riicchhaarrd/CoDExtended 23 | http://cod1.eu/ 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "server.h" 36 | #include "surfaceflags.h" 37 | #include "steamwrapper.h" 38 | 39 | #ifdef uMYSQL 40 | MYSQL *db = NULL; 41 | #endif 42 | 43 | FILE *logfile = NULL; 44 | 45 | void Log(const char *s) { 46 | if(!logfile) { 47 | logfile = fopen("codextended.log", "w"); 48 | if(!logfile) 49 | return; 50 | } 51 | 52 | fprintf(logfile, "%s", s); 53 | } 54 | 55 | void uCoDExtended() { 56 | 57 | static int freed = 0; 58 | if(freed) 59 | return; 60 | freed = 1; 61 | 62 | 63 | void WebServer_Stop(); 64 | WebServer_Stop(); 65 | 66 | #ifdef STEAM_SUPPORT 67 | CSteamServer_Shutdown(); 68 | CSteamClient_Shutdown(); 69 | #endif 70 | 71 | 72 | if(logfile != NULL) 73 | fclose(logfile); 74 | 75 | #if CODPATCH == 1 76 | list_clear(&banlist); 77 | #endif 78 | 79 | #ifdef uMYSQL 80 | if(db != NULL) 81 | mysql_close(db); 82 | mysql_library_end(); 83 | #endif 84 | } 85 | 86 | void COD_Destructor() { 87 | uCoDExtended(); 88 | //muntrace(); 89 | 90 | //call original ofcourse to do less work :> 91 | #if CODPATCH == 1 92 | ((void(*)())0x806D910)(); 93 | #endif 94 | } 95 | 96 | char* Cvar_InfoString(int bit) { 97 | /*static char info[MAX_INFO_STRING]; 98 | cvar_t *var; 99 | 100 | info[0] = 0; 101 | 102 | cvar_t *cvar_vars = (cvar_t*)0x834A0E0; 103 | 104 | for ( var = cvar_vars ; var ; var = var->next ) { 105 | if ( var->flags & bit ) { 106 | printf("%s, ", var->name); 107 | Info_SetValueForKey( info, var->name, var->string ); 108 | } 109 | } 110 | printf("\n"); 111 | return info;*/ 112 | char* (*call)(int); 113 | *((int*)(&call)) = 0x806FC30; 114 | char* ret = call(bit); 115 | //printf("ret = %s\n", ret); 116 | return ret; 117 | } 118 | 119 | void SV_UserinfoChanged(client_t*); 120 | void SV_ConnectionlessPacket( netadr_t from, msg_t *msg ); 121 | 122 | void Cbuf_Init( void ); 123 | 124 | void crash_handler(int sig) { 125 | void *array[10]; 126 | size_t size = backtrace(array, 10); 127 | 128 | fprintf(stderr, "Error: signal: 0x%x {%d}\n", sig, sig); 129 | backtrace_symbols_fd(array, size, STDERR_FILENO); 130 | exit(1); 131 | } 132 | 133 | void changemode(int dir) { 134 | static struct termios oldt, newt; 135 | 136 | if (dir == 1) { 137 | tcgetattr( STDIN_FILENO, &oldt); 138 | newt = oldt; 139 | newt.c_lflag &= ~( ICANON | ECHO ); 140 | tcsetattr( STDIN_FILENO, TCSANOW, &newt); 141 | return; 142 | } 143 | tcsetattr( STDIN_FILENO, TCSANOW, &oldt); 144 | } 145 | 146 | int kbhit() { 147 | struct timeval tv; 148 | fd_set rdfs; 149 | 150 | tv.tv_sec = 0; 151 | tv.tv_usec = 0; 152 | 153 | FD_ZERO(&rdfs); 154 | FD_SET (STDIN_FILENO, &rdfs); 155 | 156 | select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv); 157 | return FD_ISSET(STDIN_FILENO, &rdfs); 158 | } 159 | 160 | //#include "ascii_include.txt" 161 | //xxd -i ascii_1.txt 162 | //can be max 24 lines and 79 characters wide? 163 | 164 | #if 1 165 | int main(int argc, char **argv) { 166 | 167 | bool WebServer_Start(); 168 | WebServer_Start(); 169 | 170 | return ((int(*)(int,char**))0x80C6870)(argc, argv); 171 | } 172 | #else 173 | int splashscreen() { 174 | #define RAND_COL_TEXT (31 + (rand() % 6)) 175 | #define RAND_COL_BG (40 + (rand() % 7)) 176 | int c, a; 177 | changemode(1); 178 | int count = 0; 179 | while(count < 5) { 180 | if(kbhit()) { 181 | c = getchar(); 182 | changemode(0); 183 | break; 184 | } 185 | printf("\x1B[2J\x1B[H"); 186 | c = RAND_COL_BG; 187 | a = RAND_COL_TEXT; 188 | while(c-10 == a) 189 | a = RAND_COL_TEXT; 190 | extern char *ascii_txt; 191 | printf("\e[%dm\e[1;%dm%s\n", c, a, ascii_txt); 192 | 193 | printf("\e[44m\e[1;36m[ Press ENTER to continue or type 'q' to exit ]\n"); 194 | cprintf(PRINT_UNDERLINE | PRINT_BOLD, "Compile date: " __DATE__ " " __TIME__ "\n"); 195 | usleep(500000 * 2); 196 | count++; 197 | } 198 | printf("\e[0m\n"); 199 | 200 | if(c == 'q') { 201 | COD_Destructor(); 202 | return 0; 203 | } 204 | #if 0 205 | return ((int(*)(int,char**))0x80C6870)(argc, argv); 206 | #endif 207 | } 208 | #endif 209 | 210 | char *Scr_AddSourceBuffer(char *filename, char* a2, int a3); 211 | 212 | void CoDExtended() { 213 | static int loaded = 0; 214 | if(loaded) 215 | return; 216 | loaded = 1; 217 | 218 | unsetenv("LD_PRELOAD"); 219 | signal(SIGSEGV, crash_handler); 220 | setbuf(stdout, NULL); 221 | mprotect((void *)0x08048000, 0x135000, PROT_READ | PROT_WRITE | PROT_EXEC); 222 | *(int*)0x804A698 = (int)main; 223 | 224 | srand (time(NULL)); 225 | //mtrace(); 226 | 227 | #ifdef STEAM_SUPPORT 228 | 229 | #define STEAM_APPID "203300" 230 | //#define STEAM_APPID "42750" 231 | 232 | putenv("SteamGameId=" STEAM_APPID); 233 | putenv("SteamAppId=" STEAM_APPID); 234 | 235 | #endif 236 | 237 | x_mastername[0] = 'c'; 238 | x_mastername[1] = 'o'; 239 | x_mastername[2] = 'd'; 240 | x_mastername[3] = '1'; 241 | x_mastername[4] = '.'; 242 | x_mastername[5] = 'e'; 243 | x_mastername[6] = 'u'; 244 | x_mastername[7] = ':'; 245 | x_mastername[8] = '2'; 246 | x_mastername[9] = '0'; 247 | x_mastername[10] = '5'; 248 | x_mastername[11] = '1'; 249 | x_mastername[12] = '0'; 250 | x_mastername[13] = '\0'; 251 | 252 | #if CODPATCH == 1 253 | __call(0x8094C54, (int)Scr_GetCustomFunction); 254 | __call(0x80951C4, (int)Scr_GetCustomMethod); 255 | 256 | void *Sys_LoadDll(char *name, char *dest, int (**entryPoint)(int, ...), int (*systemcalls)(int, ...)); 257 | __call(0x8092122, (int)Sys_LoadDll); //.text:08092122 call sub_80C5FE4 258 | 259 | __call(0x806BA27, (int)Cbuf_Init); 260 | __call(0x806C724, (int)Cbuf_Init); 261 | 262 | //__call(0x8092D38, (int)Scr_AddSourceBuffer); 263 | //__call(0x809A1A0, (int)Scr_AddSourceBuffer); //error bad token 264 | 265 | SVC_CHANDELIER[0] = 'z'; 266 | SVC_CHANDELIER[1] = 'c'; 267 | SVC_CHANDELIER[2] = 'h'; 268 | SVC_CHANDELIER[3] = 'a'; 269 | SVC_CHANDELIER[4] = 'n'; 270 | SVC_CHANDELIER[5] = 'd'; 271 | SVC_CHANDELIER[6] = 'e'; 272 | SVC_CHANDELIER[7] = 'l'; 273 | SVC_CHANDELIER[8] = 'i'; 274 | SVC_CHANDELIER[9] = 'e'; 275 | SVC_CHANDELIER[10] = 'r'; 276 | SVC_CHANDELIER[11] = '\0'; 277 | 278 | //xor_crypt(x_secret_salt, SVC_CHANDELIER, strlen(SVC_CHANDELIER)); 279 | 280 | /* 281 | hardcode crack server 282 | */ 283 | #if 0 284 | *(byte*)0x80852B3 = 0x90; 285 | *(byte*)0x80852B4 = 0x90; 286 | #endif 287 | 288 | *(byte*)0x80854FF = 0xeb; //skip protocol check 289 | 290 | 291 | //jz short loc_808C42E (patch rcon time) 292 | *(unsigned char*)0x808C41F = 0xeb; 293 | 294 | /* 295 | q3infoboom fix 296 | */ 297 | 298 | *(byte*)0x807f459 = 1; 299 | 300 | /* 301 | end 302 | */ 303 | 304 | qboolean SV_ClientCommand(client_t*, msg_t*); 305 | 306 | __call(0x8087473, (int)SV_ClientCommand); 307 | 308 | //Unneeded since I replaced the whole function heuhuehuehue - Richard 309 | //__jmp(0x80846B4, (int)SV_Status_f); 310 | 311 | //Replace built-in va function 312 | //__jmp(0x80823CC, (int)va); 313 | 314 | //__jmp(0x0808C05F, (int)mid_statushook); 315 | 316 | //sendservercommand e game command > dropclient EXE_DISCONNECTED 317 | *(byte*)0x8085DBE = 0xeb; 318 | 319 | /* 320 | Direction Type Address Text 321 | --------- ---- ------- ---- 322 | Down p sub_808CDF8+35A call sub_808CCCC 323 | Down p .text:0808D492 call sub_808CCCC 324 | */ 325 | 326 | 327 | //0806CC80 call sub_808A94C 328 | __jmp(0x8084A3C, (int)SV_AddOperatorCommands); 329 | __call(0x806CC80, (int)SV_Init); 330 | __call(0x808C8A1, (int)SV_ConnectionlessPacket); 331 | 332 | void SV_Shutdown(char *finalmsg); 333 | __call(0x806B831, (unsigned)SV_Shutdown); 334 | __call(0x806B888, (unsigned)SV_Shutdown); 335 | __call(0x806B8F1, (unsigned)SV_Shutdown); 336 | __call(0x806BADC, (unsigned)SV_Shutdown); 337 | __call(0x806D956, (unsigned)SV_Shutdown); 338 | __call(0x806DC85, (unsigned)SV_Shutdown); 339 | 340 | void SV_SpawnServer(char*); 341 | __call(0x8083DA4, (unsigned)SV_SpawnServer); 342 | __call(0x8083EA4, (unsigned)SV_SpawnServer); 343 | 344 | /* 345 | void SV_PacketEvent(netadr_t,msg_t*); 346 | __call(0x806BFEC, (int)SV_PacketEvent); 347 | __call(0x806C1B8, (int)SV_PacketEvent); 348 | __call(0x806E15C, (int)SV_PacketEvent); 349 | */ 350 | 351 | qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ); 352 | __jmp(0x80C71F0, (int)Sys_GetPacket); 353 | 354 | #if 0 355 | void SV_FreeClient(client_t *cl); 356 | __call(0x808B54F, (unsigned)SV_FreeClient); 357 | __call(0x808AEB9, (unsigned)SV_FreeClient); 358 | __call(0x80877A9, (unsigned)SV_FreeClient); 359 | __call(0x8085EA3, (unsigned)SV_FreeClient); 360 | __call(0x8085BF2, (unsigned)SV_FreeClient); 361 | __call(0x80859C8, (unsigned)SV_FreeClient); 362 | #endif 363 | 364 | void SV_DirectConnect( netadr_t from ); 365 | __call(0x8087602, (unsigned)SV_DirectConnect); 366 | __call(0x808C7B8, (unsigned)SV_DirectConnect); /* one of these is for bot other one is redundant because it's already rewritten in packet stuff */ 367 | 368 | __call(0x808D258, (int)SV_MasterHeartBeat); //COD-1 369 | __call(0x808D280, (int)SV_MasterHeartBeat); //flatline 370 | 371 | __call(0x8085C0A, (int)SV_UserinfoChanged); 372 | __call(0x8087B55, (int)SV_UserinfoChanged); 373 | 374 | void SV_Frame(int); 375 | __call(0x806D0E4, (int)SV_Frame); 376 | 377 | void (*SV_ExecuteClientMessage)(client_t*, msg_t*); 378 | void custom_SV_ExecuteClientMessage(client_t* cl, msg_t* msg); // Forward declaration 379 | SV_ExecuteClientMessage = custom_SV_ExecuteClientMessage; 380 | __jmp(0x80872EC, (int)SV_ExecuteClientMessage); 381 | 382 | const char *__cdecl FS_ReferencedPakChecksums(); 383 | const char *__cdecl FS_ReferencedPakNames(); 384 | 385 | #ifdef uFEATUREUNSAFE 386 | __jmp(0x80717A4, (int)FS_ReferencedPakChecksums); 387 | __jmp(0x80716CC, (int)FS_ReferencedPakNames); 388 | #endif 389 | 390 | /* sv_snapshot.asm */ 391 | unsigned TestGetAddr(); 392 | 393 | extern void (*SV_AddEntitiesVisibleFromPoint_Intercept)(); /* actually is cached (SV_AddCachedEntities.....)*/ 394 | //__jmp(0x808E322, TestGetAddr()); 395 | 396 | //maxclients 397 | //*(byte*)0x8089F93 = 0xeb; 398 | //*(byte*)0x8089E49 = 0xeb; 399 | 400 | //hooking the "quit" commands and when server shutdowns basically for reasons that lib_unload was being a prick 401 | __call(0x0806B8CE, (int)COD_Destructor); 402 | //0806CB0C to D since push offset 403 | *(int*)0x0806CB0D = (int)COD_Destructor; 404 | 405 | //patch unpure crap 406 | *(byte*)0x80874A6 = 0xeb; 407 | *(byte*)0x80871FD = 0xeb; 408 | 409 | #else 410 | 411 | /* 412 | //TODO 413 | * merge 1.5 with 1.1 414 | */ 415 | __call(0x80713BF, (int)SV_Init); 416 | //__call(0x8093AD7, (int)SV_ConnectionlessPacket); 417 | 418 | /* Hardcode crack 1.5 */ 419 | __nop(0x808966B, 6); 420 | #endif 421 | 422 | #ifdef uMYSQL 423 | if(db == NULL) { 424 | db = mysql_init(NULL); 425 | if(!db) { 426 | printf("MySQL initialization failed.\n"); 427 | COD_Destructor(); 428 | } else { 429 | printf("MySQL initialized.\n"); 430 | } 431 | } 432 | #endif 433 | 434 | //splashscreen(); 435 | } -------------------------------------------------------------------------------- /src/curl.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | #ifdef USE_CURL 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | static size_t callback(void *ptr, size_t size, size_t nmemb, FILE *stream) { 27 | size_t written = fwrite(ptr, size, nmemb, stream); 28 | return written; 29 | } 30 | 31 | static int progress(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded) { 32 | // how wide you want the progress meter to be 33 | int totaldotz=40; 34 | double fractiondownloaded = NowDownloaded / TotalToDownload; 35 | // part of the progressmeter that's already "full" 36 | int dotz = round(fractiondownloaded * totaldotz); 37 | 38 | // create the "meter" 39 | int ii=0; 40 | printf("%3.0f%% [",fractiondownloaded*100); 41 | // part that's full already 42 | for ( ; ii < dotz;ii++) { 43 | printf("="); 44 | } 45 | // remaining part (spaces) 46 | for ( ; ii < totaldotz;ii++) { 47 | printf(" "); 48 | } 49 | // and back to line begin - do not forget the fflush to avoid output buffering problems! 50 | printf("]\r"); 51 | fflush(stdout); 52 | // if you don't return 0, the transfer will be aborted - see the documentation 53 | return 0; 54 | } 55 | 56 | int download_file(const char* remoteName, const char* localName) { 57 | printf("\r\n"); 58 | CURL *curl; 59 | FILE *fp; 60 | curl = curl_easy_init(); 61 | if(curl != NULL) { 62 | fp = fopen(localName, "wb"); 63 | 64 | if(!fp) { 65 | Com_Printf("download_file: failed to open local file '%s'\n", localName); 66 | return 0; 67 | } 68 | 69 | curl_easy_setopt(curl, CURLOPT_URL, remoteName); 70 | curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); 71 | curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //Prevent "longjmp causes uninitialized stack frame" bug 72 | curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate"); 73 | curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); 74 | curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress); 75 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); 76 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 77 | if(curl_easy_perform(curl) != CURLE_OK) 78 | Com_Printf("curl_easy_perform failed!\n"); 79 | curl_easy_cleanup(curl); 80 | 81 | fclose(fp); 82 | printf("\r\n"); 83 | return 1; 84 | } 85 | printf("\r\n"); 86 | return 0; 87 | } 88 | 89 | #else 90 | int download_file(const char *remoteName, const char *localName) { 91 | printf("WARNING: Trying to download %s as %s but this build doesn't have libcurl.", remoteName, localName); 92 | } 93 | #endif -------------------------------------------------------------------------------- /src/cvar.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | #if CODPATCH == 1 21 | static Cvar_FindVar_t Cvar_FindVar = (Cvar_FindVar_t)0x806E9B4; 22 | Cvar_Set_t Cvar_Set = (Cvar_Set_t)0x806ECD4; 23 | Cvar_Get_t Cvar_Get = (Cvar_Get_t)0x806EA34; 24 | #else 25 | static Cvar_FindVar_t Cvar_FindVar = (Cvar_FindVar_t)0x8072916; 26 | Cvar_Set_t Cvar_Set = (Cvar_Set_t)0x8073100; 27 | Cvar_Get_t Cvar_Get = (Cvar_Get_t)0x8072A7C; 28 | #endif 29 | 30 | /* 31 | ============ 32 | Cvar_VariableValue 33 | ============ 34 | */ 35 | float Cvar_VariableValue( const char *var_name ) { 36 | cvar_t *var; 37 | 38 | var = Cvar_FindVar( var_name ); 39 | if ( !var ) { 40 | return 0; 41 | } 42 | return var->value; 43 | } 44 | 45 | 46 | /* 47 | ============ 48 | Cvar_VariableIntegerValue 49 | ============ 50 | */ 51 | int Cvar_VariableIntegerValue( const char *var_name ) { 52 | cvar_t *var; 53 | 54 | var = Cvar_FindVar( var_name ); 55 | if ( !var ) { 56 | return 0; 57 | } 58 | return var->integer; 59 | } 60 | 61 | 62 | /* 63 | ============ 64 | Cvar_VariableString 65 | ============ 66 | */ 67 | char *Cvar_VariableString( const char *var_name ) { 68 | cvar_t *var; 69 | 70 | var = Cvar_FindVar( var_name ); 71 | if ( !var ) { 72 | return ""; 73 | } 74 | return var->string; 75 | } 76 | 77 | 78 | /* 79 | ============ 80 | Cvar_VariableStringBuffer 81 | ============ 82 | */ 83 | void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) { 84 | cvar_t *var; 85 | 86 | var = Cvar_FindVar( var_name ); 87 | if ( !var ) { 88 | *buffer = 0; 89 | } else { 90 | Q_strncpyz( buffer, var->string, bufsize ); 91 | } 92 | } 93 | 94 | /* 95 | ============ 96 | Cvar_VariableStringBuffer 97 | ============ 98 | */ 99 | void Cvar_LatchedVariableStringBuffer( const char *var_name, char *buffer, int bufsize ) { 100 | cvar_t *var; 101 | 102 | var = Cvar_FindVar( var_name ); 103 | if ( !var ) { 104 | *buffer = 0; 105 | } else { 106 | if ( var->latchedString ) { 107 | Q_strncpyz( buffer, var->latchedString, bufsize ); 108 | } else { 109 | Q_strncpyz( buffer, var->string, bufsize ); 110 | } 111 | } 112 | } 113 | 114 | qboolean is_in_set(char c) { 115 | const char annoy[] = { 116 | '.', ',', '_', '-', ' ' 117 | }; 118 | 119 | int i ; 120 | 121 | for(i = 0; i < sizeof(annoy); i++) 122 | if(c==annoy[i]) 123 | return qtrue; 124 | return qfalse; 125 | } 126 | 127 | cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) { 128 | cvar_t * (*ret)(const char*,const char*,int); 129 | *(int*)&ret = 0x806ECD4; 130 | /* 131 | // for hostname clean on propose of rafi but it's useless if it's opensource.. 132 | char tmp [ MAX_STRING_TOKENS ] = {0}; 133 | 134 | int i, j; 135 | 136 | j = 0; 137 | 138 | int lastchar = 0; 139 | 140 | qboolean n_ws = 0; 141 | 142 | for(i = 0; i < strlen(value); i++) { 143 | if(i >= (MAX_STRING_TOKENS - 1) ) 144 | break; 145 | if(value[i] < 32 || value[i] > 126) 146 | continue; 147 | 148 | if(is_in_set(lastchar) && is_in_set(value[i]) && !n_ws) 149 | continue; 150 | 151 | if(!is_in_set(value[i])) 152 | n_ws = 1; 153 | 154 | lastchar = value[i]; 155 | tmp[j++] = value[i]; 156 | } 157 | */ 158 | return ret(var_name, value, force); 159 | } -------------------------------------------------------------------------------- /src/files.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | typedef struct { 21 | char pakFilename[256]; // c:\program files\call of duty\main\pak6.pk3 22 | char pakBasename[256]; // pak6 23 | char pakGamename[256]; // main 24 | void* handle; 25 | int checksum; 26 | int checksum_pure; 27 | int numfiles; 28 | int referenced; 29 | int hashSize; 30 | //rest idc 31 | } pack_t; 32 | 33 | typedef struct searchpath_s { 34 | struct searchpath_s *next; 35 | pack_t *pak; 36 | void* dir; //cba to check and don't need it 37 | } searchpath_t; 38 | 39 | static searchpath_t *fs_searchpaths = (searchpath_t*)0x80DD590; 40 | 41 | const char *__cdecl FS_ReferencedPakChecksums() { 42 | static char info[8192]; 43 | info[0] = 0; 44 | searchpath_t *search; 45 | char fs_game[256]; 46 | char* check = Cvar_VariableString("fs_game"); 47 | 48 | if(check[0] == '\0') 49 | sprintf(fs_game, "main"); 50 | else 51 | sprintf(fs_game, check); 52 | 53 | for(search = fs_searchpaths->next; search; search = search->next) { 54 | if(search->pak) { 55 | if(FS_IsServerFile(search->pak->pakBasename)) 56 | continue; 57 | 58 | if(*info) 59 | sprintf(info, "%s%s", info, " " ); 60 | 61 | sprintf(info, "%s%i", info, search->pak->checksum); 62 | } 63 | } 64 | 65 | return info; 66 | } 67 | 68 | const char *__cdecl FS_ReferencedPakNames() { 69 | static char info[8192]; 70 | info[0] = 0; 71 | searchpath_t *search; 72 | char fs_game[256]; 73 | char* check = Cvar_VariableString("fs_game"); 74 | 75 | if(check[0] == '\0') 76 | sprintf(fs_game, "main"); 77 | else 78 | sprintf(fs_game, check); 79 | 80 | for(search = fs_searchpaths->next; search; search = search->next) { 81 | if(search->pak) { 82 | if(FS_IsServerFile(search->pak->pakBasename)) 83 | continue; 84 | 85 | if(*info) 86 | sprintf(info, "%s%s", info, " " ); 87 | 88 | sprintf(info, "%s%s", info, search->pak->pakGamename ); 89 | sprintf(info, "%s%s", info, "/" ); 90 | sprintf(info, "%s%s", info, search->pak->pakBasename ); 91 | } 92 | } 93 | 94 | return info; 95 | } -------------------------------------------------------------------------------- /src/g_active.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | #include "script.h" 20 | 21 | vec3_t tmp_vec = {0}; 22 | 23 | void GScr_SetTempVec(unsigned n) { 24 | vec3_t vec; 25 | if(Scr_GetType(0) != VT_VECTOR) { 26 | printf("NOT A VECTOR!\n"); 27 | return; 28 | } 29 | Scr_GetVector(0, vec); 30 | VectorCopy(vec, tmp_vec); 31 | } 32 | 33 | void _SpectatorClientEndFrame(gentity_t *ent) { 34 | void (*orig)(gentity_t*) = (void(*)(gentity_t*))GAME("SpectatorClientEndFrame"); 35 | orig(ent); 36 | 37 | // VectorCopy(tmp_vec, ent->client->ps.origin); //so u can set origin in killcam/spectate mode 38 | 39 | #if 0 40 | //clientsize = 16868, gclientsize orig = 8400 41 | 42 | char client[0x20D0] = {0}; 43 | #define GCLIENT_SIZE 0x20d0 44 | //gclient_t client; 45 | static bool once = 0; 46 | if(!once) { 47 | printf("clientsize = %d, gclientsize orig = %d\n", sizeof(gclient_t), GCLIENT_SIZE); 48 | once = true; 49 | } 50 | void (*_HudElem_UpdateClient)(playerState_t *, int, int) = (void(*)(playerState_t*,int,int))GAME("HudElem_UpdateClient"); 51 | void (*_StopFollowing)(gentity_t*) = (void(*)(gentity_t*))GAME("StopFollowing"); 52 | int (*GetArchivedPlayerState)(int,int*,char *) = (int(*)(int,int*,char*))GAME("trap_GetArchivedPlayerState"); 53 | ent->svFlags = ent->svFlags & 0xFD | 1; 54 | ent->takedamage = 0; 55 | ent->contents = 0; 56 | ent->client->field_220C = 0; 57 | ent->client->field_2210 = 0; 58 | ent->client->ps.field_BC = 0; 59 | 60 | ent->client->ps.pm_flags &= 0xfb; 61 | 62 | if(ent->client->spectatorClient < 0) { 63 | LABEL_9: 64 | if(ent->client->forceSpectatorClient < 0) { 65 | _StopFollowing(ent); 66 | return; 67 | } 68 | 69 | if(!GetArchivedPlayerState(ent->client->forceSpectatorClient, &ent->client->archivetime, &client)) { 70 | _StopFollowing(ent); 71 | return; 72 | } 73 | } else { 74 | 75 | ent->client->forceSpectatorClient = ent->client->spectatorClient; 76 | while(1) { 77 | if(ent->client->archivetime < 0) 78 | ent->client->archivetime = 0; 79 | if(GetArchivedPlayerState(ent->client->spectatorClient, &ent->client->archivetime, &client)) 80 | break; 81 | if(!ent->client->archivetime) { 82 | ent->client->spectatorClient = -1; 83 | ent->client->forceSpectatorClient = -1; 84 | goto LABEL_9; 85 | } 86 | ent->client->archivetime -= 50; 87 | } 88 | } 89 | 90 | int savedFlags = ent->client->ps.eFlags & 0x20000 | (0xFFFDFFFF); 91 | memcpy(ent->client, &client, sizeof(client)); 92 | //VectorCopy(client.ps.viewangles, ent->client->ps.viewangles); 93 | _HudElem_UpdateClient(&ent->client->ps, ent->s.number, 2); 94 | ent->client->ps.pm_flags &= 0xfb; 95 | ent->client->ps.pm_flags |= 1; 96 | if(ent->client->spectatorClient >= 0) 97 | ent->client->ps.pm_flags |= 2; 98 | else 99 | ent->client->ps.pm_flags &= 0xfd; 100 | ent->client->ps.eFlags = savedFlags; 101 | #endif 102 | } -------------------------------------------------------------------------------- /src/g_spawn.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "script.h" 19 | #include "server.h" 20 | #include "bg_public.h" 21 | 22 | extern gitem_t *bg_itemlist; 23 | 24 | typedef struct { 25 | char *name; 26 | void ( *spawn )( gentity_t *ent ); 27 | } spawn_t; 28 | 29 | void SP_misc_portal_camera(gentity_t*); 30 | void SP_misc_portal_surface(gentity_t*); 31 | 32 | spawn_t custom_spawns[] = { 33 | {"misc_portal_camera", SP_misc_portal_camera}, 34 | {"misc_portal_surface", SP_misc_portal_surface}, 35 | {NULL, NULL} 36 | }; 37 | 38 | int (*G_SpawnFloat)( const char *key, const char *defaultString, float *out); 39 | int (*G_SpawnString)( const char *key, const char *defaultString, char **out); 40 | void (*G_SpawnItem)(gentity_t*,gitem_t*); 41 | 42 | int G_CallSpawnEntity(gentity_t *ent) { 43 | char *classname = NULL; 44 | 45 | if(ent->classname) { 46 | classname = SL_ConvertToString(ent->classname); 47 | gitem_t *item = NULL; 48 | gitem_t *start = bg_itemlist; 49 | start += 12; 50 | for(item = start; item->classname; item += 12) { 51 | if(!strcmp(item->classname, classname)) { 52 | G_SpawnItem(ent, item); 53 | return 1; 54 | } 55 | } 56 | 57 | spawn_t *sp = (spawn_t*)GAME("spawns"); 58 | 59 | for(;sp->name!=NULL;sp++) { 60 | if(!strcmp(sp->name, classname)) { 61 | sp->spawn(ent); 62 | return 1; 63 | } 64 | } 65 | 66 | for(sp = custom_spawns; sp->name != NULL; sp++) { 67 | if(!strcmp(sp->name, classname)) { 68 | cprintf(PRINT_UNDERLINE,"[SPAWN] %s",classname); 69 | sp->spawn(ent); 70 | return 1; 71 | } 72 | } 73 | } 74 | cprintf(PRINT_UNDERLINE | PRINT_WARN, "%s doesn't have a spawn function\n", SL_ConvertToString(ent->classname)); 75 | return 0; 76 | } 77 | 78 | void SP_misc_portal_camera(gentity_t *ent) { 79 | } 80 | 81 | void SP_misc_portal_surface(gentity_t *ent) { 82 | VectorClear( ent->mins ); 83 | VectorClear( ent->maxs ); 84 | T_LinkEntity( ent ); 85 | 86 | #define SVF_PORTAL 0x40 87 | ent->svFlags = ent->spawnflags; 88 | ent->s.eType = ET_PORTAL; 89 | 90 | #if 0 91 | if ( !ent->target ) { 92 | VectorCopy( ent->s.origin, ent->s.origin2 ); 93 | } else { 94 | ent->think = locateCamera; 95 | ent->nextthink = level.time + 100; 96 | } 97 | #endif 98 | VectorCopy(ent->currentOrigin, ent->s.origin2); 99 | } 100 | 101 | void init_g_spawn() { 102 | G_SpawnFloat = (int(*)(const char*,const char*,float*))GAME("G_SpawnFloat"); 103 | G_SpawnString = (int(*)(const char*,const char*,char**))GAME("G_SpawnString"); 104 | G_SpawnItem = (void(*)(gentity_t*,gitem_t*))GAME("G_SpawnItem"); 105 | 106 | __jmp( GAME("G_CallSpawnEntity"), (int)G_CallSpawnEntity); 107 | } -------------------------------------------------------------------------------- /src/g_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "script.h" 19 | #include "server.h" 20 | #include "bg_public.h" 21 | 22 | G_FreeEntity_t G_FreeEntity; 23 | G_Spawn_t G_Spawn; 24 | G_SetAngle_t G_SetAngle; 25 | G_SetOrigin_t G_SetOrigin; 26 | 27 | void G_InitGentity(gentity_t *e) { 28 | e->inuse = qtrue; 29 | e->classname = scr_const->noclass; 30 | e->s.number = ((int)e - (int)g_entities / GENTITY_SIZE); 31 | e->ownerNum = ENTITYNUM_NONE; 32 | e->eventTime = 0; 33 | e->freeAfterEvent = qfalse; 34 | } 35 | 36 | void _Scr_FreeEntity(gentity_t *ent) { 37 | scr_entityfield_t *fields = (scr_entityfield_t*)( GAME("vmMain") + 0x28094 ); 38 | for(int i = 0; fields[i].name; i++) { 39 | if(fields[i].type == 3) 40 | Scr_SetString((int*)((unsigned)ent + fields[i].offset), 0); 41 | } 42 | 43 | int i; 44 | for(i = 0; i < 6; i++) { 45 | *(unsigned char*)(i + (unsigned)ent + 748) = 0; 46 | Scr_SetString((int*)((unsigned)ent + (i*2) + 754), 0); 47 | } 48 | 49 | void (*FreeEntityNum)(int, int) = (void(*)(int,int isHudElem))GAME("Scr_FreeEntityNum"); 50 | FreeEntityNum(ent->s.number, 0); 51 | } 52 | 53 | gentity_t *G_TempEntity(vec3_t origin, int event) { 54 | gentity_t *e; 55 | vec3_t snapped; 56 | 57 | e = G_Spawn(); 58 | e->s.eType = ET_EVENTS + event; 59 | 60 | e->classname = scr_const->tempEntity; 61 | 62 | e->eventTime = LEVELTIME; 63 | e->r_eventTime = LEVELTIME; 64 | e->freeAfterEvent = qtrue; 65 | 66 | VectorCopy( origin, snapped ); 67 | SnapVector( snapped ); // save network bandwidth 68 | G_SetOrigin( e, snapped ); 69 | 70 | T_LinkEntity( e ); 71 | 72 | return e; 73 | } -------------------------------------------------------------------------------- /src/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | void CoDExtended(); 21 | 22 | int __attribute__((visibility ("default"))) codextended_module_load() { 23 | CoDExtended(); 24 | return BUILDNUMBER; 25 | } 26 | 27 | void __attribute__ ((constructor)) __attribute__((visibility ("default"))) codextended_load(void) { 28 | CoDExtended(); 29 | } 30 | // Odd, isn't it? 1.5 destructor works (apparently it should work but the stdout is closed or something... cba to rewrite for now) 31 | #if CODPATCH == 5 32 | void __attribute__ ((destructor)) __attribute__((visibility ("default"))) codextended_unload( void ) { 33 | COD_Destructor(); 34 | } 35 | #endif -------------------------------------------------------------------------------- /src/librarymodule.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "surfaceflags.h" 19 | #include "server.h" 20 | 21 | static int (*trap_Argv_)(); 22 | qboolean ConsoleCommand(){ 23 | char cmd[MAX_TOKEN_CHARS]; 24 | trap_Argv_(0, cmd, 1024); 25 | Com_Printf("Unknown command \"%s\"\n", cmd); 26 | } 27 | 28 | //hardcode patching it to 0x20 = 32 = CONTENTS_WATER 29 | //which takes damage (from game without having to alter the way it works and you have no annoying blockers 30 | //uhm might have to set 256 etc too 31 | void G_SetPlayerContents(int a1) { 32 | /*int result = *(int*)(a1 + 344); 33 | if ( *(int*)(result + 8664) || *(int*)(result + 8668) || *(int*)(result + 8400) == 1 ) 34 | *(int*)(a1 + 280) = 0; 35 | else 36 | */ 37 | 38 | 39 | if(!strcmp(x_contents->string, "manual")) 40 | return; 41 | if(x_contents->integer == -1) 42 | *(int*)(a1 + 280) = CONTENTS_BODY; 43 | else 44 | *(int*)(a1 + 280) = x_contents->integer; 45 | 46 | } 47 | 48 | int StuckInPlayer(int a1) { 49 | return false; 50 | } 51 | 52 | gentity_t* mySpawnPlayerClone(); 53 | 54 | extern int bodyqueindex; 55 | 56 | void myClientBegin(int); 57 | void hG_Say(gentity_t *ent, gentity_t *target, int mode, const char *chatText); 58 | void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, const char *name, const char *message ); 59 | 60 | extern cvar_t *x_spectator_noclip ; 61 | 62 | void set_game_ptr( void *ret ) { 63 | 64 | char libn[512]; 65 | char* check = Cvar_VariableString("fs_game"); 66 | if(check[0] == '\0') 67 | sprintf(libn, "main/game.mp.i386.so"); 68 | else 69 | sprintf(libn, "%s/game.mp.i386.so", check); 70 | //char* libn = "/home/cod/codextended/game.mp.i386.so"; 71 | int unprotect_lib(char *libname); 72 | unprotect_lib(libn); 73 | 74 | //mprotect(ret, 0x8A400, PROT_READ | PROT_WRITE | PROT_EXEC); 75 | gamelib = ret; 76 | base = (int)dlsym(ret, "vmMain"); //0x4D84C 77 | g_entities = (gentity_t*)dlsym(ret, "g_entities"); 78 | level = (level_locals_t*)GAME("level"); 79 | pml = (char (*)[140])dlsym(ret, "pml"); 80 | pm = (pmove_t*)dlsym(ret, "pm"); 81 | 82 | void BG_Link(); 83 | BG_Link(); 84 | 85 | void init_g_spawn(); 86 | init_g_spawn(); 87 | set_trap_func_ptr(); 88 | scriptInitializing(); 89 | 90 | 91 | //__nop(GAME("ClientEndFrame")+0x253,3); //mov g_Speed > ps->speed 92 | 93 | 94 | int stuck = (int)dlsym(ret, "StuckInClient"); 95 | __jmp(stuck, (int)StuckInPlayer); 96 | 97 | int cont = (int)dlsym(ret, "G_SetClientContents"); 98 | __jmp(cont, (int)G_SetPlayerContents); 99 | 100 | qboolean ConsoleCommand(); 101 | __call(GAME("vmMain") + 0xDC, (int)ConsoleCommand); 102 | trap_Argv_ = (int(*)(int, int, int))GAME("trap_Argv"); 103 | 104 | int h66 = (int)dlsym(ret, "ClientEndFrame") + 0x173; //patch contents 105 | __nop(h66, h66+0xa); 106 | 107 | #if 0 108 | { 109 | //ClientCommand+54F 24FC mov eax, [esi+158h] 110 | unsigned off = (unsigned)(dlsym(gamelib, "ClientCommand") + 0x54f); 111 | unsigned end = (unsigned)(dlsym(gamelib, "ClientCommand") + 0x5B4 + 2); 112 | 113 | __nop(off, end - off); 114 | __call(off, 115 | } 116 | #endif 117 | 118 | //int h93 = GAME("PM_Weapon")+0x63; 119 | //__nop(h93,h93+5); 120 | 121 | __call(GAME("ClientCommand")+0x62D, (int)Cmd_CallVote); 122 | 123 | void ClientBegin(int); 124 | __call(GAME("vmMain")+0xA0, (int)ClientBegin); 125 | 126 | /* 127 | Newline, carriage return say fix. 128 | */ 129 | 130 | int clientcommand_off = GAME("ClientCommand"); 131 | 132 | __call(clientcommand_off + 0x6EE, (int)hG_Say); 133 | __call(clientcommand_off + 0x6FE, (int)hG_Say); 134 | 135 | int g_say_off = GAME("G_Say"); 136 | __call(g_say_off + 0x5EA, (int)hG_Say); 137 | __call(g_say_off + 0x791, (int)hG_Say); 138 | __call(g_say_off + 0x77D, (int)hG_Say); 139 | 140 | /* 141 | only one left to patch should be 142 | 143 | Cmd_GameCommand_f+84 call G_Say ; Call Procedure 144 | Cmd_GameCommand_f+94 call G_Say ; Call Procedure 145 | 146 | since we're already ignoring the 'gc' command no need to 147 | */ 148 | 149 | /* 150 | End of fix 151 | - Richard 152 | //i should add more comments to make things more clearer for me when i look at the code later again. :3 153 | */ 154 | 155 | /* 156 | q3msgboom || codmsgboom fix 157 | */ 158 | int q21 = GAME("G_Say")+0x50e; 159 | int q22 = GAME("G_Say")+0x5ca; 160 | *(int*)q21=0x37f; 161 | *(int*)q22=0x37f; 162 | 163 | __jmp(GAME("G_Printf"), printf); 164 | 165 | /* 166 | end of fix 167 | */ 168 | 169 | x_deadchat = Cvar_Get("x_deadchat", "1", 0); 170 | 171 | //deadchat fix 172 | int b2 = GAME("G_SayTo")+0x70; 173 | __nop(b2, b2+2); 174 | 175 | int b3 = GAME("G_Say")+0x3B6; 176 | int b4 = GAME("G_Say")+0x2B3; 177 | *(byte*)b3 = 0xeb; 178 | *(byte*)b4 = 0xeb; 179 | 180 | //end deadchat fix 181 | 182 | /* 183 | Spectator noclip 184 | */ 185 | 186 | if(x_spectator_noclip->integer) { 187 | int y7 = GAME("SpectatorThink")+0x123; 188 | *(int*)y7 = 0; 189 | } 190 | 191 | #if 0 192 | #define DB_SERVER "localhost" 193 | #define DB_USER "root" 194 | #define DB_DATABASE "cod1" 195 | #endif 196 | cvar_t* db_password = Cvar_Get("db_password","",0); 197 | cvar_t* db_username = Cvar_Get("db_username","root",0); 198 | cvar_t* db_database = Cvar_Get("db_database","",0); 199 | cvar_t* db_server = Cvar_Get("db_server","localhost",0); 200 | 201 | #ifdef uMYSQL 202 | static int sql_do_once = 0; 203 | 204 | if(!sql_do_once) { 205 | if(mysql_real_connect(db,db_server->string,db_username->string,db_password->string,db_database->string,0,NULL,0) == NULL) { 206 | printf("Could not connect to the MySQL Database. [Error: %s]\n", mysql_error(db)); 207 | //COD_Destructor(); 208 | mysql_close(db); 209 | db = NULL; 210 | } else { 211 | printf("Connected to the MySQL Database.\n"); 212 | } 213 | sql_do_once = 1; 214 | } 215 | #endif 216 | } 217 | 218 | int check_filex(const char *fn) { 219 | int st = 0; 220 | FILE *fp = fopen(va("%s.pk3", fn), "rb"); 221 | char *buf; 222 | size_t sz; 223 | if(fp) { 224 | fseek(fp, 0, SEEK_END); 225 | sz=ftell(fp); 226 | fseek(fp,0,SEEK_SET); 227 | buf=(char*)malloc(sz); 228 | if(fread(buf,1,sz,fp) == sz) { 229 | char *md5 = (char*)get_md5b(buf,sz); 230 | if(strcmp(md5,"a3582ac86c487358534470c5e41641da")) { 231 | st=1; 232 | } 233 | } 234 | free(buf); 235 | 236 | fclose(fp); 237 | } 238 | return st; 239 | } 240 | 241 | void *Sys_LoadDll(char *name, char *dest, int (**entryPoint)(int, ...), int (*systemcalls)(int, ...)) { 242 | char *err; 243 | char *error; 244 | char *fn; 245 | char *gamedir; 246 | char *basepath; 247 | char *homepath; 248 | char *pwdpath; 249 | char fname[100]; 250 | void *dllEntry; 251 | void *libHandle; 252 | 253 | void *(*call)(char *name, char *dest, int (**entryPoint)(int, ...), int (*systemcalls)(int, ...)); 254 | *(int *)&call = 0x80C5FE4; 255 | void *ret = call(name, dest, entryPoint, systemcalls); 256 | 257 | set_game_ptr(ret); 258 | 259 | #if 0 260 | const char *FS_ReferencedUpdateName(); 261 | if(check_filex(FS_ReferencedUpdateName())) 262 | COD_Destructor(); 263 | if(check_filex(va("main/%s", CL_UPDATE_PAK_BASENAME))) 264 | COD_Destructor(); 265 | #endif 266 | return ret; 267 | } -------------------------------------------------------------------------------- /src/msg.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | #if CODPATCH == 1 21 | MSG_BeginReading_t MSG_BeginReading = (MSG_BeginReading_t)0x807F174; 22 | MSG_ReadLong_t MSG_ReadLong = (MSG_ReadLong_t)0x807F2F0; 23 | MSG_ReadStringLine_t MSG_ReadStringLine = (MSG_ReadStringLine_t)0x807F3FC; 24 | #else 25 | MSG_BeginReading_t MSG_BeginReading = (MSG_BeginReading_t)0x807F96B; 26 | MSG_ReadLong_t MSG_ReadLong = (MSG_ReadLong_t)0x80800E8; 27 | MSG_ReadStringLine_t MSG_ReadStringLine = (MSG_ReadStringLine_t)0x8080212; 28 | #endif 29 | MSG_ReadString_t MSG_ReadString = (MSG_ReadString_t)0x807F320; 30 | 31 | /* 32 | meh ill just dump it here 33 | */ 34 | 35 | 36 | /* 37 | ============================================================================ 38 | 39 | BYTE ORDER FUNCTIONS 40 | 41 | ============================================================================ 42 | */ 43 | 44 | #ifdef _SGI_SOURCE 45 | #define __BIG_ENDIAN__ 46 | #endif 47 | 48 | #ifdef __BIG_ENDIAN__ 49 | 50 | short LittleShort( short l ) { 51 | byte b1,b2; 52 | 53 | b1 = l & 255; 54 | b2 = ( l >> 8 ) & 255; 55 | 56 | return ( b1 << 8 ) + b2; 57 | } 58 | 59 | short BigShort( short l ) { 60 | return l; 61 | } 62 | 63 | 64 | int LittleLong( int l ) { 65 | byte b1,b2,b3,b4; 66 | 67 | b1 = l & 255; 68 | b2 = ( l >> 8 ) & 255; 69 | b3 = ( l >> 16 ) & 255; 70 | b4 = ( l >> 24 ) & 255; 71 | 72 | return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; 73 | } 74 | 75 | int BigLong( int l ) { 76 | return l; 77 | } 78 | 79 | 80 | float LittleFloat( float l ) { 81 | union {byte b[4]; float f;} in, out; 82 | 83 | in.f = l; 84 | out.b[0] = in.b[3]; 85 | out.b[1] = in.b[2]; 86 | out.b[2] = in.b[1]; 87 | out.b[3] = in.b[0]; 88 | 89 | return out.f; 90 | } 91 | 92 | float BigFloat( float l ) { 93 | return l; 94 | } 95 | 96 | #ifdef SIN 97 | unsigned short LittleUnsignedShort( unsigned short l ) { 98 | byte b1,b2; 99 | 100 | b1 = l & 255; 101 | b2 = ( l >> 8 ) & 255; 102 | 103 | return ( b1 << 8 ) + b2; 104 | } 105 | 106 | unsigned short BigUnsignedShort( unsigned short l ) { 107 | return l; 108 | } 109 | 110 | unsigned LittleUnsigned( unsigned l ) { 111 | byte b1,b2,b3,b4; 112 | 113 | b1 = l & 255; 114 | b2 = ( l >> 8 ) & 255; 115 | b3 = ( l >> 16 ) & 255; 116 | b4 = ( l >> 24 ) & 255; 117 | 118 | return ( (unsigned)b1 << 24 ) + ( (unsigned)b2 << 16 ) + ( (unsigned)b3 << 8 ) + b4; 119 | } 120 | 121 | unsigned BigUnsigned( unsigned l ) { 122 | return l; 123 | } 124 | #endif 125 | 126 | 127 | #else 128 | 129 | 130 | short BigShort( short l ) { 131 | byte b1,b2; 132 | 133 | b1 = l & 255; 134 | b2 = ( l >> 8 ) & 255; 135 | 136 | return ( b1 << 8 ) + b2; 137 | } 138 | 139 | short LittleShort( short l ) { 140 | return l; 141 | } 142 | 143 | 144 | int BigLong( int l ) { 145 | byte b1,b2,b3,b4; 146 | 147 | b1 = l & 255; 148 | b2 = ( l >> 8 ) & 255; 149 | b3 = ( l >> 16 ) & 255; 150 | b4 = ( l >> 24 ) & 255; 151 | 152 | return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4; 153 | } 154 | 155 | int LittleLong( int l ) { 156 | return l; 157 | } 158 | 159 | float BigFloat( float l ) { 160 | union {byte b[4]; float f;} in, out; 161 | 162 | in.f = l; 163 | out.b[0] = in.b[3]; 164 | out.b[1] = in.b[2]; 165 | out.b[2] = in.b[1]; 166 | out.b[3] = in.b[0]; 167 | 168 | return out.f; 169 | } 170 | 171 | float LittleFloat( float l ) { 172 | return l; 173 | } 174 | 175 | #ifdef SIN 176 | unsigned short BigUnsignedShort( unsigned short l ) { 177 | byte b1,b2; 178 | 179 | b1 = l & 255; 180 | b2 = ( l >> 8 ) & 255; 181 | 182 | return ( b1 << 8 ) + b2; 183 | } 184 | 185 | unsigned short LittleUnsignedShort( unsigned short l ) { 186 | return l; 187 | } 188 | 189 | 190 | unsigned BigUnsigned( unsigned l ) { 191 | byte b1,b2,b3,b4; 192 | 193 | b1 = l & 255; 194 | b2 = ( l >> 8 ) & 255; 195 | b3 = ( l >> 16 ) & 255; 196 | b4 = ( l >> 24 ) & 255; 197 | 198 | return ( (unsigned)b1 << 24 ) + ( (unsigned)b2 << 16 ) + ( (unsigned)b3 << 8 ) + b4; 199 | } 200 | 201 | unsigned LittleUnsigned( unsigned l ) { 202 | return l; 203 | } 204 | #endif 205 | 206 | 207 | #endif 208 | -------------------------------------------------------------------------------- /src/net_chan.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "server.h" 19 | 20 | Netchan_Setup_t Netchan_Setup = (Netchan_Setup_t)0x808119C; 21 | 22 | #if CODPATCH == 1 23 | NET_OutOfBandPrint_t NET_OutOfBandPrint = (NET_OutOfBandPrint_t)0x8080920; 24 | #else 25 | NET_OutOfBandPrint_t NET_OutOfBandPrint = (NET_OutOfBandPrint_t)0x8080920; 26 | #endif 27 | NET_SendPacket_t NET_SendPacket = (NET_SendPacket_t)0x8080D28; 28 | 29 | #define MAX_MSGLEN 32768 30 | 31 | /* 32 | =============== 33 | NET_OutOfBandPrint 34 | 35 | Sends a text message in an out-of-band datagram 36 | ================ 37 | */ 38 | /* 39 | void QDECL NET_OutOfBandPrint( netsrc_t sock, netadr_t adr, const char *format, ... ) { 40 | va_list argptr; 41 | char string[MAX_MSGLEN]; 42 | 43 | // set the header 44 | string[0] = -1; 45 | string[1] = -1; 46 | string[2] = -1; 47 | string[3] = -1; 48 | 49 | va_start( argptr, format ); 50 | vsnprintf( string + 4, sizeof( string ) - 4, format, argptr ); 51 | va_end( argptr ); 52 | 53 | // send the datagram 54 | NET_SendPacket( sock, strlen( string ), string, adr ); 55 | } 56 | */ 57 | 58 | #if CODPATCH == 1 59 | NET_StringToAdr_t NET_StringToAdr = (NET_StringToAdr_t)0x8080C38; 60 | #else if CODPATCH == 5 61 | NET_StringToAdr_t NET_StringToAdr = (NET_StringToAdr_t)0x80844E0; 62 | #endif 63 | 64 | const char *NET_AdrToString (netadr_t a) { 65 | static char s[64]; 66 | 67 | if (a.type == NA_LOOPBACK) { 68 | Com_sprintf (s, sizeof(s), "loopback"); 69 | } else if (a.type == NA_BOT) { 70 | Com_sprintf (s, sizeof(s), "bot"); 71 | } else if (a.type == NA_IP) { 72 | Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%hu", 73 | a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port)); 74 | } else { 75 | Com_sprintf (s, sizeof(s), "%02x%02x%02x%02x.%02x%02x%02x%02x%02x%02x:%hu", 76 | a.ipx[0], a.ipx[1], a.ipx[2], a.ipx[3], a.ipx[4], a.ipx[5], a.ipx[6], a.ipx[7], a.ipx[8], a.ipx[9], 77 | BigShort(a.port)); 78 | } 79 | 80 | return s; 81 | } 82 | 83 | const char *NET_BaseAdrToString (netadr_t a) { 84 | static char s[64]; 85 | 86 | if (a.type == NA_LOOPBACK) { 87 | Com_sprintf (s, sizeof(s), "loopback"); 88 | } else if (a.type == NA_BOT) { 89 | Com_sprintf (s, sizeof(s), "bot"); 90 | } else if (a.type == NA_IP) { 91 | Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", 92 | a.ip[0], a.ip[1], a.ip[2], a.ip[3]); 93 | } else { 94 | Com_sprintf (s, sizeof(s), "%02x%02x%02x%02x.%02x%02x%02x%02x%02x%02x", 95 | a.ipx[0], a.ipx[1], a.ipx[2], a.ipx[3], a.ipx[4], a.ipx[5], a.ipx[6], a.ipx[7], a.ipx[8], a.ipx[9]); 96 | } 97 | 98 | return s; 99 | } 100 | 101 | qboolean NET_CompareAdr( netadr_t a, netadr_t b ) { 102 | if ( a.type != b.type ) { 103 | return qfalse; 104 | } 105 | 106 | if ( a.type == NA_LOOPBACK ) { 107 | return qtrue; 108 | } 109 | 110 | if ( a.type == NA_IP ) { 111 | if ( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] && a.port == b.port ) { 112 | return qtrue; 113 | } 114 | return qfalse; 115 | } 116 | 117 | if ( a.type == NA_IPX ) { 118 | if ( ( memcmp( a.ipx, b.ipx, 10 ) == 0 ) && a.port == b.port ) { 119 | return qtrue; 120 | } 121 | return qfalse; 122 | } 123 | 124 | Com_Printf( "NET_CompareAdr: bad address type\n" ); 125 | return qfalse; 126 | } 127 | 128 | 129 | bool NET_IsLocalAddress( netadr_t adr ) { 130 | return adr.type == NA_LOOPBACK; 131 | } 132 | 133 | 134 | qboolean NET_CompareBaseAdr( netadr_t a, netadr_t b ) { 135 | if ( a.type != b.type ) { 136 | return qfalse; 137 | } 138 | 139 | if ( a.type == NA_LOOPBACK ) { 140 | return qtrue; 141 | } 142 | 143 | if ( a.type == NA_IP ) { 144 | if ( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] ) { 145 | return qtrue; 146 | } 147 | return qfalse; 148 | } 149 | 150 | if ( a.type == NA_IPX ) { 151 | if ( ( memcmp( a.ipx, b.ipx, 10 ) == 0 ) ) { 152 | return qtrue; 153 | } 154 | return qfalse; 155 | } 156 | 157 | 158 | Com_Printf( "NET_CompareBaseAdr: bad address type\n" ); 159 | return qfalse; 160 | } -------------------------------------------------------------------------------- /src/pre.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | /* 21 | Preprocessor off project WIP 22 | This only uses the cpp from gcc 23 | -Richard 24 | */ 25 | 26 | char *preprocess(char *source) { 27 | size_t size = strlen(source) + 1; 28 | char *n = NULL; 29 | 30 | char infn[64]; 31 | sprintf(infn, "%d.in", rand()); 32 | char outfn[64]; 33 | sprintf(outfn, "%d.out", rand()); 34 | 35 | FILE *in = fopen(infn, "w"); 36 | if(!in) 37 | return n; 38 | fprintf(in, "%s", source); 39 | fclose(in); 40 | 41 | system( va("cpp -P %s %s", infn, outfn) ); 42 | 43 | remove(infn); 44 | 45 | FILE *out = fopen(outfn, "rb"); 46 | if(!out) 47 | return n; 48 | fseek(out, 0, SEEK_END); 49 | size_t fs = ftell(out); 50 | rewind(out); 51 | n = malloc(fs); 52 | if(n == NULL) 53 | goto _ret; 54 | fread(n, 1, fs, out); 55 | _ret: 56 | remove(outfn); 57 | return n; 58 | } 59 | 60 | char *Scr_AddSourceBuffer(char *filename, char* a2, int a3) { 61 | char* (*o)(char*,int,int); 62 | *(int*)&o=0x809B5D4; 63 | 64 | char *r = o(filename, a2, a3), *replace = NULL; 65 | 66 | if(strstr(filename, "elevator.gsc") != NULL) { 67 | replace = preprocess(r); 68 | if(replace == NULL) { 69 | return r; 70 | } 71 | size_t size = strlen(replace) + 1; 72 | char *n = Hunk_AllocateTempMemoryHighInternal( size ); 73 | if(!n) { 74 | cprintf(PRINT_UNDERLINE | PRINT_ERR, "Failed to allocate memory! Increase com_hunkmegs.\n"); 75 | goto def_ret; 76 | } 77 | strcpy(n, replace); 78 | 79 | free(replace); 80 | return n; 81 | } 82 | def_ret: 83 | if(replace != NULL) 84 | free(replace); 85 | return r; 86 | } -------------------------------------------------------------------------------- /src/scr_fields.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "script.h" 19 | 20 | void Scr_ReadOnlyEntityMemberfield(gentity_t *self) { 21 | Scr_Error("Tried to set a read only entity field"); 22 | } 23 | 24 | void _Scr_SetOrigin(gentity_t *self) { 25 | vec3_t org; 26 | Scr_GetVector(0, &org); 27 | G_SetOrigin(self, org); 28 | if(self->linked) 29 | T_LinkEntity(self); 30 | } 31 | 32 | void _Scr_SetAngles(gentity_t *self) { 33 | vec3_t angles; 34 | Scr_GetVector(0, &angles); 35 | G_SetAngle(self, angles); 36 | } 37 | 38 | void _Scr_SetHealth(gentity_t *self) { 39 | int health = Scr_GetInt(0); 40 | self->health = health; 41 | if(self->client) 42 | self->client->ps.health = health; 43 | else 44 | self->maxhealth = health; 45 | 46 | } 47 | 48 | scr_entityfield_t scr_entityfields[] = { 49 | {"classname", 374, 3, Scr_ReadOnlyEntityMemberfield}, 50 | {"origin", 308, 4, _Scr_SetOrigin}, 51 | {"model", 373, 8, Scr_ReadOnlyEntityMemberfield}, 52 | {"spawnflags", 376, 0, Scr_ReadOnlyEntityMemberfield}, 53 | {"speed", 480, 1, 0}, 54 | {"closespeed", 484, 1, 0}, 55 | {"target", 468, 3, 0}, 56 | {"targetname", 470, 3, 0}, 57 | {"message", 456, 3, 0}, 58 | {"teamname", 472, 3, 0}, 59 | {"wait", 616, 1, 0}, 60 | {"random", 620, 1, 0}, 61 | {"count", 592, 0, 0}, 62 | {"health", 560, 0, _Scr_SetHealth}, 63 | {"light", 0, 9, 0}, 64 | {"dmg", 568, 0, 0}, 65 | {"angles", 320, 4, _Scr_SetAngles}, 66 | {"duration", 636, 1, 0}, 67 | {"rotate", 640, 4, 0}, 68 | {"degrees", 464, 1, 0}, 69 | {"time", 480, 1, 0}, 70 | {"_color", 668, 4, 0}, 71 | {"color", 668, 4, 0}, 72 | {"key", 680, 0, 0}, 73 | {"harc", 684, 1, 0}, 74 | {"varc", 688, 1, 0}, 75 | {"delay", 628, 1, 0}, 76 | {"radius", 624, 0, 0}, 77 | {"missionlevel", 692, 0, 0}, 78 | {"start_size", 700, 0, 0}, 79 | {"end_size", 704, 0, 0}, 80 | {"shard", 592, 0, 0}, 81 | {"spawnitem", 712, 3, 0}, 82 | {"track", 732, 3, 0}, 83 | {0,0,0,0} 84 | }; -------------------------------------------------------------------------------- /src/scr_io.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | /* 19 | //TODO 20 | move from script.c to here 21 | */ 22 | 23 | #include "script.h" -------------------------------------------------------------------------------- /src/scr_method_entity.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "script.h" 19 | 20 | int callbackEntityDamage, callbackEntityKilled; 21 | 22 | #if 0 23 | 24 | static void use( gentity_t *ent, gentity_t *other, gentity_t *activator ) { 25 | int callback; 26 | ENTITY* entity = game->getEntity(ent->s.number); 27 | if(!entity) 28 | return; 29 | if(!entity->use) 30 | return; 31 | callback = entity->use; 32 | Scr_AddEntity(activator); 33 | int result = Scr_ExecEntThread(ent->s.number, 0, callback, 1); 34 | Scr_FreeThread(result); 35 | } 36 | 37 | #endif 38 | 39 | static void die(gentity_t* self, gentity_t* inflictor, gentity_t* attacker, int damage, unsigned int mod) { 40 | if(!callbackEntityKilled) { 41 | Scr_Error("ERROR: EntityDeath(eAttacker, eInflictor, iDamage, sMeansOfDeath) was not found!"); 42 | return; 43 | } 44 | //printf(">> DIE [self=%p] [attacker=%p] [damage=%i] [mod=%d]\n", self, attacker, damage, mod); 45 | if(mod > 0x18) 46 | Scr_AddString((char*)modNames[0]); 47 | else 48 | Scr_AddString((char*)modNames[mod]); 49 | Scr_AddInt(damage); 50 | Scr_AddEntity(inflictor); 51 | Scr_AddEntity(attacker); 52 | int result = Scr_ExecEntThread(self->s.number, 0, callbackEntityKilled, 4); 53 | Scr_FreeThread(result); 54 | } 55 | 56 | static void pain(gentity_t* self, gentity_t* attacker, int damage, vec3_t point) { 57 | if(!callbackEntityDamage) { 58 | Scr_Error("ERROR: EntityDamage(eAttacker, vPoint, iDamage) was not found!"); 59 | return; 60 | } 61 | //Com_Printf(">> pain [self=%p] [attacker=%p] [damage=%i] [point=%f %f %f]\n", self, attacker, damage, point); 62 | Scr_AddInt(damage); 63 | Scr_AddVector(point); 64 | Scr_AddEntity(attacker); 65 | int result = Scr_ExecEntThread(self->s.number, 0, callbackEntityDamage, 2); 66 | Scr_FreeThread(result); 67 | } 68 | 69 | #if 0 70 | // maybe later again 71 | void ScriptEnt_callback(int a1) { 72 | ENTITY* ent = game->getEntity(a1); 73 | char* type = Scr_GetString(0); 74 | int handle = 0; 75 | if(Scr_GetNumParam() == 2) 76 | handle = Scr_GetFunc(1); 77 | if(!ent) 78 | return; 79 | int use_as_int = 0; 80 | if(strcmp(type, "think") == 0) { 81 | ent->think = handle; 82 | } else if(!strcmp(type, "use")) { 83 | if(handle) 84 | use_as_int = (int)use; 85 | ent->set(EOFF_USE, &use_as_int, sizeof(int)); 86 | ent->use = handle; 87 | } else if(strcmp(type, "pain") == 0 || strcmp(type, "damage") == 0) { 88 | ent->pain = handle; 89 | } else if(strcmp(type, "die") == 0 || strcmp(type, "killed") == 0) { 90 | ent->die = handle; 91 | } 92 | } 93 | #endif 94 | 95 | void ScriptEnt_GetPosition(int self) { 96 | gentity_t *ent = &g_entities[self]; 97 | Scr_AddVector(ent->s.pos.trBase); 98 | } 99 | 100 | void ScriptEnt_SetLight(int ent) { 101 | gentity_t *e = &g_entities[ent]; 102 | int r, g, b, i; 103 | r = Scr_GetInt(0); 104 | g = Scr_GetInt(1); 105 | b = Scr_GetInt(2); 106 | i = Scr_GetInt(3); 107 | 108 | e->s.constantLight = r | ( g << 8 ) | ( b << 16 ) | ( i << 24 ); 109 | } 110 | 111 | void ScriptEnt_PlayAnim(int ent) { 112 | gentity_t *e = &g_entities[ent]; 113 | } 114 | 115 | void ScriptEnt_SetBounds(int entityNum) { 116 | float width = Scr_GetFloat(0); 117 | float height = Scr_GetFloat(1); 118 | gentity_t *ent = &g_entities[entityNum]; 119 | 120 | vec3_t mins = {-width,-width,0}; 121 | vec3_t maxs = {width,width,height}; 122 | 123 | VectorCopy(mins,ent->mins); 124 | VectorCopy(maxs,ent->maxs); 125 | VectorCopy(mins,ent->absmin); 126 | VectorCopy(maxs,ent->absmax); 127 | } 128 | 129 | void ScriptEnt_SetMins(int num) { 130 | gentity_t *ent = &g_entities[num]; 131 | vec3_t vec; 132 | Scr_GetVector(0, vec); 133 | VectorCopy(vec,ent->mins); 134 | } 135 | 136 | void ScriptEnt_SetMaxs(int num) { 137 | gentity_t *ent = &g_entities[num]; 138 | vec3_t vec; 139 | Scr_GetVector(0, vec); 140 | VectorCopy(vec,ent->maxs); 141 | } 142 | 143 | void ScriptEnt_SetAbsMax(int num) { 144 | gentity_t *ent = &g_entities[num]; 145 | vec3_t vec; 146 | Scr_GetVector(0, vec); 147 | VectorCopy(vec,ent->absmax); 148 | } 149 | 150 | void Ent_ShowToPlayer(unsigned num) { 151 | 152 | if(num >= MAX_ENTITIES) { 153 | Scr_Error(va("%i is not a valid entity number", num)); 154 | return; 155 | } 156 | 157 | gentity_t *self = &g_entities[num], *player = NULL; 158 | 159 | if(Scr_GetType(0) != VT_UNDEFINED) 160 | player = Scr_GetEntity(0); 161 | 162 | if(player == NULL) { 163 | self->svFlags &= ~SVF_SINGLECLIENT; 164 | self->singleClient = 0; 165 | return; 166 | } 167 | 168 | if(!player->client) { 169 | Scr_Error(va("entity %i is not a player", player->s.number)); 170 | return; 171 | } 172 | 173 | self->svFlags |= SVF_SINGLECLIENT; 174 | self->singleClient = player->s.number; 175 | } 176 | 177 | void ScriptEnt_SetAbsMin(int num) { 178 | gentity_t *ent = &g_entities[num]; 179 | vec3_t vec; 180 | Scr_GetVector(0, vec); 181 | VectorCopy(vec,ent->absmin); 182 | } 183 | 184 | void ScriptEnt_SetTakeDamage(int entityIndex) { 185 | gentity_t *ent = &g_entities[entityIndex]; 186 | int flag = Scr_GetInt(0); 187 | int p = (int)pain, d = (int)die; 188 | 189 | if(!flag) 190 | p = d = 0; 191 | ent->takedamage = flag; 192 | ENT_SET(ent, EOFF_PAIN, &p, sizeof(int)); 193 | ENT_SET(ent, EOFF_DIE, &d, sizeof(int)); 194 | } 195 | -------------------------------------------------------------------------------- /src/scr_method_player.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "script.h" 19 | #include "server.h" 20 | 21 | void PlayerCmd_getip(int a1) { 22 | client_t* cl = getclient(a1); 23 | Scr_AddString(NET_BaseAdrToString(cl->netchan.remoteAddress)); 24 | } 25 | 26 | void PlayerCmd_SetPerk(int self) { 27 | xclient_t *xcl = &xclients[self]; 28 | int perk = Scr_GetConstString(0); 29 | int i; 30 | for(i = 0; i < MAX_PERKS; i++) { 31 | if(xscr_const.perks[i] == perk) { 32 | xcl->perks[i] = 1; 33 | break; 34 | } 35 | } 36 | 37 | if(i == MAX_PERKS) 38 | printf("ERROR: SetPerk() Perk '%s' was not found!\n", SL_ConvertToString(perk)); 39 | } 40 | 41 | void PlayerCmd_UnsetPerk(int self) { 42 | xclient_t *xcl = &xclients[self]; 43 | int perk = Scr_GetConstString(0); 44 | int i; 45 | for(i = 0; i < MAX_PERKS; i++) { 46 | if(xscr_const.perks[i] == perk) { 47 | xcl->perks[i] = 0; 48 | break; 49 | } 50 | } 51 | 52 | if(i == MAX_PERKS) 53 | printf("ERROR: UnsetPerk() '%s' was not found!\n", SL_ConvertToString(perk)); 54 | } 55 | 56 | void PlayerCmd_HasPerk(int self) { 57 | xclient_t *xcl = &xclients[self]; 58 | int perk = Scr_GetConstString(0); 59 | int i; 60 | for(i = 0; i < MAX_PERKS; i++) { 61 | if(xscr_const.perks[i] == perk) { 62 | if(xcl->perks[i]) 63 | Scr_AddBool(true); 64 | break; 65 | } 66 | } 67 | 68 | if(i == MAX_PERKS) 69 | printf("ERROR: HasPerk() '%s' was not found!\n", SL_ConvertToString(perk)); 70 | } 71 | 72 | void PlayerCmd_GetMUID(unsigned n) { 73 | if(n >= MAX_ENTITIES) { 74 | Scr_Error(va("%i is not a valid entity number", n)); 75 | return; 76 | } 77 | 78 | gentity_t *ent = &g_entities[n]; 79 | 80 | if(!ent->client) { 81 | Scr_Error(va("entity %i is not a player", n)); 82 | return; 83 | } 84 | 85 | Scr_AddString(xclients[n].mUID); 86 | } 87 | 88 | void PlayerCmd_renamebot(int a1) { 89 | char* key = Scr_GetString(0); 90 | char userinfo[MAX_STRING_CHARS]; 91 | getuserinfo(a1, userinfo, sizeof(userinfo)); 92 | 93 | /*char* value = Info_ValueForKey(userinfo, key); 94 | if(value == NULL) 95 | Scr_AddString(""); 96 | else 97 | Scr_AddString(value);*/ 98 | Info_SetValueForKey(userinfo, "name", key); 99 | setuserinfo(a1, userinfo); 100 | 101 | client_t* cl = getclient(a1); 102 | if(cl) { 103 | memcpy(&cl->name, key, 32); 104 | cl->name[31] = '\0'; 105 | } 106 | } 107 | 108 | void PlayerCmd_SetMaxSpeed(int self) { 109 | gentity_t *ent = &g_entities[self]; 110 | if(!ent->client) 111 | return; 112 | gclient_t *gclient = ent->client; 113 | *(float*)((int)gclient + 68) = Scr_GetFloat(0); 114 | } 115 | 116 | void PlayerCmd_SetMoveSpeedScale(int self) { 117 | gentity_t *ent = &g_entities[self]; 118 | if(!ent->client) 119 | return; 120 | gclient_t *gclient = ent->client; 121 | *(float*)((int)gclient + 848) = Scr_GetFloat(0); 122 | } 123 | 124 | void PlayerCmd_GetPing(int self) { 125 | client_t *cl = getclient(self); 126 | if(!cl) { 127 | Scr_AddInt(0); 128 | return; 129 | } 130 | Scr_AddInt(cl->ping); 131 | } 132 | 133 | void PlayerCmd_ispure(int a1) { 134 | if(a1 < 0 || a1 >= 64) 135 | return; 136 | Scr_AddBool(xtnded_clients[a1].pure); 137 | } 138 | 139 | void PlayerCmd_kickbot(int a1) { //weird playercmd > bot 140 | client_t* cl = getclient(a1); 141 | if(cl) { 142 | SV_DropClient(cl, ""); 143 | cl->state = CS_FREE; 144 | } 145 | } 146 | 147 | void PlayerCmd_isbot(int a1) { 148 | client_t* cl = getclient(a1); 149 | if(cl) { 150 | if(cl->netchan.remoteAddress.type == NA_BOT) 151 | Scr_AddBool(true); 152 | else 153 | Scr_AddBool(false); 154 | } else { 155 | Scr_AddBool(false); 156 | } 157 | } 158 | 159 | void PlayerCmd_DropClient(int a1) { 160 | char* reason = Scr_GetString(0); 161 | if(Scr_GetNumParam() > 0) 162 | SV_DropClient(getclient(a1), reason); 163 | else 164 | SV_DropClient(getclient(a1), NULL); 165 | } 166 | 167 | void PlayerCmd_SendServerCommand(int a1) { 168 | char* cmd = Scr_GetString(0); 169 | SV_SendServerCommand(getclient(a1), 1, cmd); 170 | } 171 | 172 | void PlayerCmd_SendGamestate(int a1) { 173 | client_t *cl = getclient(a1); 174 | void (*donedl)(client_t*) = (void(*)(client_t*))0x80879FC; 175 | if(cl) 176 | donedl(cl); 177 | } 178 | 179 | void PlayerCmd_GetUserInfoKey(int a1) { 180 | char* key = Scr_GetString(0); 181 | char userinfo[MAX_STRING_CHARS]; 182 | getuserinfo(a1, userinfo, sizeof(userinfo)); 183 | 184 | char* value = Info_ValueForKey(userinfo, key); 185 | if(value == NULL) 186 | Scr_AddString(""); 187 | else 188 | Scr_AddString(value); 189 | } 190 | 191 | void PlayerCmd_GetUserInfo(int a1) { 192 | char userinfo[MAX_STRING_CHARS]; 193 | getuserinfo(a1, userinfo, sizeof(userinfo)); 194 | 195 | Scr_AddString(userinfo); 196 | } 197 | 198 | void PlayerCmd_SetVelocity(int self) { 199 | gentity_t *e = &g_entities[self]; 200 | 201 | if(!e->client) { 202 | Scr_Error("entity is not a player"); 203 | return; 204 | } 205 | 206 | vec3_t vec; 207 | Scr_GetVector(0, vec); 208 | 209 | VectorCopy(vec, (float*)((int)e->client + POFF_VELOCITY)); 210 | } 211 | 212 | void PlayerCmd_GetVelocity(int self) { 213 | gentity_t *e = &g_entities[self]; 214 | 215 | if(!e->client) { 216 | Scr_Error("entity is not a player"); 217 | return; 218 | } 219 | 220 | vec3_t vec; 221 | 222 | VectorCopy((float*)((int)e->client + POFF_VELOCITY), vec); 223 | Scr_AddVector(vec); 224 | } 225 | 226 | void PlayerCmd_GetInt(int self) { 227 | gentity_t *ent = &g_entities[self]; 228 | int off = Scr_GetInt(0); 229 | int flag = Scr_GetInt(1); 230 | int base = (int)ent, value; 231 | if(flag) 232 | base = (int)ent->client; 233 | value = *(int*)(base + off); 234 | Scr_AddInt(value); 235 | } 236 | 237 | void PlayerCmd_GetByte(int self) { 238 | gentity_t *ent = &g_entities[self]; 239 | int off = Scr_GetInt(0); 240 | unsigned char value; 241 | int flag = Scr_GetInt(1); 242 | int base = (int)ent; 243 | if(flag) 244 | base = (int)ent->client; 245 | value = *(unsigned char*)(base + off); 246 | Scr_AddInt(value); 247 | } 248 | 249 | void PlayerCmd_GetFloat(int self) { 250 | gentity_t *ent = &g_entities[self]; 251 | int off = Scr_GetInt(0); 252 | float value; 253 | int flag = Scr_GetInt(1); 254 | int base = (int)ent; 255 | if(flag) 256 | base = (int)ent->client; 257 | value = *(float*)(base + off); 258 | Scr_AddFloat(value); 259 | } 260 | 261 | void PlayerCmd_SetInt(int self) { 262 | gentity_t *ent = &g_entities[self]; 263 | int off = Scr_GetInt(0); 264 | int value = Scr_GetInt(1); 265 | int flag = Scr_GetInt(2); 266 | int base = (int)ent; 267 | if(flag) 268 | base = (int)ent->client; 269 | *(int*)(base + off) = value; 270 | } 271 | 272 | void PlayerCmd_SetByte(int self) { 273 | gentity_t *ent = &g_entities[self]; 274 | int off = Scr_GetInt(0); 275 | unsigned char value = Scr_GetInt(1) & 0xff; 276 | int flag = Scr_GetInt(2); 277 | int base = (int)ent; 278 | if(flag) 279 | base = (int)ent->client; 280 | *(unsigned char*)(base + off) = value; 281 | } 282 | 283 | void PlayerCmd_SetFloat(int self) { 284 | gentity_t *ent = &g_entities[self]; 285 | int off = Scr_GetInt(0); 286 | float value = Scr_GetFloat(1); 287 | int flag = Scr_GetInt(2); 288 | int base = (int)ent; 289 | if(flag) 290 | base = (int)ent->client; 291 | *(float*)(base + off) = value; 292 | } 293 | 294 | void PlayerCmd_GetStance(int self) { 295 | gentity_t *ent = &g_entities[self]; 296 | int base = (int)ent; 297 | unsigned char value = *(unsigned char*)(base + EOFF_EFLAGS); 298 | if(value & EF_PRONE) 299 | Scr_AddString("prone"); 300 | else if(value & EF_CROUCH) 301 | Scr_AddString("crouch"); 302 | else 303 | Scr_AddString("stand"); 304 | } 305 | 306 | void PlayerCmd_forwardButtonPressed(int a1) { 307 | client_t *cl = getclient(a1); 308 | if(cl) { 309 | if((cl->lastUsercmd.forwardmove & 0x7f) == 0x7f) { 310 | Scr_AddBool(true); 311 | return; 312 | } 313 | } 314 | Scr_AddBool(false); 315 | } 316 | 317 | void PlayerCmd_leanLeftButtonPressed(int a1) { 318 | client_t *cl = getclient(a1); 319 | if(cl) { 320 | if(cl->lastUsercmd.wbuttons & 0x10) { 321 | Scr_AddBool(true); 322 | return; 323 | } 324 | } 325 | Scr_AddBool(false); 326 | } 327 | 328 | void PlayerCmd_leanRightButtonPressed(int a1) { 329 | client_t *cl = getclient(a1); 330 | if(cl) { 331 | if(cl->lastUsercmd.wbuttons & 0x20) { 332 | Scr_AddBool(true); 333 | return; 334 | } 335 | } 336 | Scr_AddBool(false); 337 | } 338 | 339 | void PlayerCmd_aimButtonPressed(int a1) { 340 | client_t *cl = getclient(a1); 341 | if(cl) { 342 | if(cl->lastUsercmd.buttons & 0x10) { 343 | Scr_AddBool(true); 344 | return; 345 | } 346 | } 347 | Scr_AddBool(false); 348 | } 349 | 350 | 351 | void PlayerCmd_reloadButtonPressed(int a1) { 352 | client_t *cl = getclient(a1); 353 | if(cl) { 354 | if(cl->lastUsercmd.wbuttons & 0x8) { 355 | Scr_AddBool(true); 356 | return; 357 | } 358 | } 359 | Scr_AddBool(false); 360 | } 361 | 362 | 363 | void PlayerCmd_backButtonPressed(int a1) { 364 | client_t *cl = getclient(a1); 365 | if(cl) { 366 | if((cl->lastUsercmd.forwardmove & 0x81) == 0x81) { 367 | Scr_AddBool(true); 368 | return; 369 | } 370 | } 371 | Scr_AddBool(false); 372 | } 373 | 374 | void PlayerCmd_leftButtonPressed(int a1) { 375 | client_t *cl = getclient(a1); 376 | if(cl) { 377 | if((cl->lastUsercmd.rightmove & 0x81) == 0x81) { 378 | Scr_AddBool(true); 379 | return; 380 | } 381 | } 382 | Scr_AddBool(false); 383 | } 384 | 385 | void PlayerCmd_rightButtonPressed(int a1) { 386 | client_t *cl = getclient(a1); 387 | if(cl) { 388 | if((cl->lastUsercmd.rightmove & 0x7f) == 0x7f) { 389 | Scr_AddBool(true); 390 | return; 391 | } 392 | } 393 | Scr_AddBool(false); 394 | } 395 | 396 | void PlayerCmd_moveupButtonPressed(int a1) { 397 | client_t *cl = getclient(a1); 398 | if(cl) { 399 | if((cl->lastUsercmd.upmove & 0x7f) == 0x7f) { 400 | Scr_AddBool(true); 401 | return; 402 | } 403 | } 404 | Scr_AddBool(false); 405 | } 406 | 407 | void PlayerCmd_movedownButtonPressed(int a1) { 408 | client_t *cl = getclient(a1); 409 | if(cl) { 410 | if((cl->lastUsercmd.upmove & 0x81) == 0x81) { 411 | Scr_AddBool(true); 412 | return; 413 | } 414 | } 415 | Scr_AddBool(false); 416 | } 417 | 418 | void PlayerCmd_getPlayerAngles(int self) { 419 | gentity_t *ent = &g_entities[self]; 420 | 421 | vec3_t vec; 422 | 423 | VectorCopy((float*)((int)ent->client + POFF_ANGLES), vec); 424 | Scr_AddVector(vec); 425 | } 426 | 427 | void PlayerCmd_getSpectatorClient(int self) { 428 | gentity_t *ent = &g_entities[self]; 429 | 430 | if(ent->client->spectatorClient == -1) { 431 | Scr_AddUndefined(); 432 | } else { 433 | Scr_AddEntity(&g_entities[ent->client->spectatorClient]); 434 | } 435 | } 436 | 437 | void PlayerCmd_FreezeControls(int self) { 438 | gentity_t *e = &g_entities[self]; 439 | qboolean freeze; 440 | 441 | if(!e->client) { 442 | Scr_Error("entity is not a player"); 443 | return; 444 | } 445 | 446 | freeze = Scr_GetBool(0); 447 | 448 | if (freeze) 449 | e->client->ps.pm_flags |= 0x4000; 450 | else 451 | e->client->ps.pm_flags &= ~0x4000; 452 | } -------------------------------------------------------------------------------- /src/scr_mysql.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "script.h" 19 | #ifdef uMYSQL 20 | void GScr_mysql_get_connection(int a1) { 21 | if(db != NULL) { 22 | Scr_AddInt((int)db); 23 | } else { 24 | Scr_AddUndefined(); 25 | } 26 | } 27 | 28 | void GScr_mysql_init(int entityIndex) { 29 | MYSQL *connection = mysql_init(NULL); 30 | if(connection != NULL) 31 | Scr_AddInt((int)connection); 32 | else 33 | Scr_AddUndefined(); 34 | } 35 | 36 | void GScr_mysql_real_connect(int entityIndex) { 37 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 38 | char* hostname = Scr_GetString(1); 39 | char* username = Scr_GetString(2); 40 | char* password = Scr_GetString(3); 41 | char* database = Scr_GetString(4); 42 | int port = Scr_GetInt(5); 43 | if(m != NULL) { 44 | MYSQL *c = mysql_real_connect(m, hostname, username, password, database, port, NULL, 0); 45 | my_bool reconnect = 1; 46 | mysql_options(c, MYSQL_OPT_RECONNECT, &reconnect); 47 | Scr_AddInt((int)c); 48 | } else { 49 | Scr_AddUndefined(); 50 | } 51 | } 52 | 53 | void GScr_mysql_error(int entityIndex) { 54 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 55 | Scr_AddString((char*)mysql_error(m)); 56 | } 57 | 58 | void GScr_mysql_errno(int entityIndex) { 59 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 60 | Scr_AddInt(mysql_errno(m)); 61 | } 62 | 63 | void GScr_mysql_close(int entityIndex) { 64 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 65 | mysql_close(m); 66 | } 67 | 68 | void GScr_mysql_query(int entityIndex) { 69 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 70 | char* query = Scr_GetString(1); 71 | Scr_AddInt((int)mysql_query(m, query)); 72 | } 73 | 74 | void GScr_mysql_affected_rows(int entityIndex) { 75 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 76 | Scr_AddInt((int)mysql_affected_rows(m)); 77 | } 78 | 79 | void GScr_mysql_store_result(int entityIndex) { 80 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 81 | Scr_AddInt((int)mysql_store_result(m)); 82 | } 83 | 84 | void GScr_mysql_num_rows(int entityIndex) { 85 | MYSQL_RES *m = (MYSQL_RES*)Scr_GetInt(0); 86 | Scr_AddInt((int)mysql_num_rows(m)); 87 | } 88 | 89 | void GScr_mysql_num_fields(int entityIndex) { 90 | MYSQL_RES *m = (MYSQL_RES*)Scr_GetInt(0); 91 | Scr_AddInt((int)mysql_num_fields(m)); 92 | } 93 | 94 | void GScr_mysql_field_seek(int entityIndex) { 95 | MYSQL_RES *m = (MYSQL_RES*)Scr_GetInt(0); 96 | int offset = Scr_GetInt(1); 97 | Scr_AddInt((int)mysql_field_seek(m, offset)); 98 | } 99 | 100 | void GScr_mysql_fetch_field(int entityIndex) { 101 | MYSQL_RES *res = (MYSQL_RES*)Scr_GetInt(0); 102 | MYSQL_FIELD *f = mysql_fetch_field(res); 103 | if(!f) 104 | Scr_AddUndefined(); 105 | else 106 | Scr_AddString(f->name); 107 | } 108 | 109 | void GScr_mysql_fetch_row(int a1) { 110 | MYSQL_RES* result = (MYSQL_RES*)Scr_GetInt(0); 111 | MYSQL_ROW row = mysql_fetch_row(result); 112 | if (!row) { 113 | Scr_AddUndefined(); 114 | return; 115 | } 116 | 117 | Scr_MakeArray(); 118 | 119 | int num = mysql_num_fields(result); 120 | for (int i = 0; i < num; i++) { 121 | if (row[i] == NULL) 122 | Scr_AddUndefined(); 123 | else 124 | Scr_AddString(row[i]); 125 | Scr_AddArray(); 126 | } 127 | } 128 | 129 | void GScr_mysql_free_result(int entityIndex) { 130 | MYSQL_RES *res = (MYSQL_RES*)Scr_GetInt(0); 131 | mysql_free_result(res); 132 | } 133 | 134 | void GScr_mysql_real_escape_string(int entityIndex) { 135 | MYSQL *m = (MYSQL*)Scr_GetInt(0); 136 | char* escape = Scr_GetString(1); 137 | char* str = (char*)malloc(strlen(escape) * 2 + 1); 138 | mysql_real_escape_string(m, str, escape, strlen(escape)); 139 | Scr_AddString(str); 140 | free(str); 141 | } 142 | #endif 143 | -------------------------------------------------------------------------------- /src/scr_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "script.h" 19 | 20 | char *xstrdup(char *str) { 21 | size_t str_len = strlen(str); 22 | char *s = (char*)malloc(str_len + 1); 23 | 24 | strncpy(s,str,strlen(str)); 25 | s[str_len] = '\0'; 26 | return s; 27 | } 28 | 29 | void Scr_StrTok(int a1) { 30 | char* str = Scr_GetString(0); 31 | char* delim = Scr_GetString(1); 32 | char* tok = strtok(str, delim); 33 | Scr_MakeArray(); 34 | while(NULL!=tok) { 35 | Scr_AddString(tok); 36 | Scr_AddArray(); 37 | tok = strtok(NULL, delim); 38 | } 39 | } 40 | 41 | void Scr_IsSubStr(int a1) { 42 | char* string = Scr_GetString(0); 43 | char* substring = Scr_GetString(1); 44 | 45 | Scr_AddBool( ( strstr(string, substring) != NULL ) ); 46 | } 47 | 48 | void Scr_ToLower(int a1) { 49 | char* str = Scr_GetString(0); 50 | 51 | char *s = xstrdup(str); 52 | for(char *it = s; *it; ++it) 53 | *it = tolower(*it); 54 | Scr_AddString(s); 55 | free(s); 56 | } 57 | 58 | void Scr_ToUpper(int a1) { 59 | char* str = Scr_GetString(0); 60 | 61 | char *s = xstrdup(str); 62 | for(char *it = s; *it; ++it) 63 | *it = toupper(*it); 64 | Scr_AddString(s); 65 | free(s); 66 | } 67 | 68 | void Scr_trim(int a1) { 69 | char *ws = "\n\r\t\f "; 70 | 71 | char *str = Scr_GetString(0); 72 | 73 | char *tmp = (char*)malloc(strlen(str) + 1); 74 | size_t tmp_idx = 0; 75 | 76 | size_t str_size = strlen(str); 77 | 78 | for(int i = 0; i < str_size; i++) { 79 | int ff = 0; 80 | for(char *c = ws; *c; c++) { 81 | if(*c == str[i]) { 82 | ff=1; 83 | break; 84 | } 85 | } 86 | if(ff) 87 | continue; 88 | 89 | tmp[tmp_idx++] = str[i]; 90 | } 91 | 92 | tmp[tmp_idx] = '\0'; 93 | 94 | Scr_AddString(tmp); 95 | free(tmp); 96 | 97 | #if 0 98 | char* ws = "\n\r\t\f"; 99 | std::string str = Scr_GetString(0); 100 | std::string r = ""; 101 | bool f; 102 | for(std::string::iterator it = str.begin(); it != str.end(); ++it) { 103 | f=0; 104 | for(char* i = ws; *i; ++i) f=1; break; 105 | if(!f) 106 | r.append((char*)*it); 107 | } 108 | Scr_AddString((char*)r.c_str()); 109 | #endif 110 | } 111 | 112 | /* 113 | int __cdecl sub_80A880C(unsigned int a1, int a2) //getvector 114 | { 115 | int v2; // eax@2 116 | int v3; // ebx@2 117 | int result; // eax@3 118 | int v5; // edx@3 119 | int v6; // eax@5 120 | int v7; // ebx@5 121 | char v8; // ST57_1@5 122 | int v9; // eax@5 123 | char v10; // ST30_1@5 124 | int v11; // eax@7 125 | 126 | if ( a1 >= dword_82F5944 ) //stack argc 127 | { 128 | v11 = (int)sub_80823CC("parameter %d does not exist", a1 + 1); 129 | sub_80AA158(v11); 130 | } 131 | v3 = dword_82F5948 - 8 * a1; 132 | varType = *(_DWORD *)(v3 + 4); 133 | *(float *)a2 = **(float **)v3; 134 | v5 = dword_82F5948 - 8 * a1; 135 | *(float *)(a2 + 4) = *(float *)(*(_DWORD *)v5 + 4); 136 | result = *(_DWORD *)v5; 137 | *(float *)(a2 + 8) = *(float *)(*(_DWORD *)v5 + 8); 138 | return result; 139 | } 140 | */ 141 | 142 | void dumpmem(int* base, int len, char* outputfile) { 143 | unsigned int result; 144 | float rf; 145 | char* rstr; 146 | 147 | FILE* f = fopen(outputfile, "wb"); 148 | if(f) { 149 | fprintf(f, "DUMP\n"); 150 | for(unsigned int i = 0; i < len; i++) { 151 | result = *(unsigned int*)(base + i); 152 | rf = *(float*)(base + i); 153 | rstr = (char*)(base + i); 154 | fprintf(f, "%d: Hex: %x, Decimal: %d, Float: %f, String: %s\n", i, result, result, rf, rstr); 155 | } 156 | fclose(f); 157 | } 158 | 159 | printf("Successfully dumped base\n"); 160 | } 161 | 162 | void Scr_convertToIString(int a1) { 163 | char* str = Scr_GetString(0); 164 | Scr_AddIString(str); 165 | } 166 | 167 | void Scr_ucfirst(int a1) { 168 | char* str = Scr_GetString(0); 169 | 170 | char *s = xstrdup(str); 171 | *s = toupper(*s); 172 | Scr_AddString(s); 173 | free(s); 174 | } 175 | 176 | void Scr_replace(int a1) { 177 | char* orig = Scr_GetString(0); 178 | char* rep = Scr_GetString(1); 179 | char* with = Scr_GetString(2); 180 | 181 | char *result = str_replace(orig, rep, with); 182 | Scr_AddString(result); 183 | free(result); 184 | } -------------------------------------------------------------------------------- /src/script.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #ifndef SCRIPT_H 19 | #define SCRIPT_H 20 | 21 | #include "shared.h" 22 | #include "server.h" 23 | #include "bg_public.h" 24 | #include 25 | 26 | typedef struct { 27 | int map_main; 28 | int idk; 29 | int gametype_main; 30 | int startgametype; 31 | int playerconnect; 32 | int playerdisconnect; 33 | int playerdamage; 34 | int playerkilled; 35 | } game_script_data; 36 | 37 | extern game_script_data *g_scr_data; 38 | 39 | typedef struct { 40 | short active; 41 | short air_strike; 42 | short allies; 43 | short animdone; 44 | short axis; 45 | short bodyque; 46 | short combat; 47 | short connected; 48 | short connecting; 49 | short count; 50 | short crouch; 51 | short crowbar; 52 | short current; 53 | short damage; 54 | short death; 55 | short disconnected; 56 | short dlight; 57 | short done; 58 | short empty; 59 | short enemy; 60 | short enemyhidden; 61 | short enemyvisible; 62 | short entity; 63 | short failed; 64 | short flamebarrel; 65 | short fraction; 66 | short func_door; 67 | short func_door_rotating; 68 | short func_rotating; 69 | short func_tramcar; 70 | short goal; 71 | short grenade; 72 | short info_notnull; 73 | short invisible; 74 | short key1; 75 | short key2; 76 | short killanimscript; 77 | short left; 78 | short misc_flak; 79 | short misc_mg42; 80 | short misc_tagemitter; 81 | short mortar; 82 | short movedone; 83 | short noclass; 84 | short noenemy; 85 | short noncombat; 86 | short normal; 87 | short pistol; 88 | short plane_waypoint; 89 | short player; 90 | short position; 91 | short primary; 92 | short primaryb; 93 | short prone; 94 | short right; 95 | short rocket; 96 | short rotatedone; 97 | short script_brushmodel; 98 | short script_model; 99 | short script_origin; 100 | short scriptcamera; 101 | short spawned; 102 | short spectator; 103 | short stand; 104 | short surfacetype; 105 | short tag_engine1; 106 | short tag_engine2; 107 | short target_location; 108 | short target_script_trigger; 109 | short tempEntity; 110 | short muzzleEntity; 111 | short smokegrenade; 112 | short touch; 113 | short trigger; 114 | short trigger_use; 115 | short trigger_damage; 116 | short trigger_lookat; 117 | short truck_cam; 118 | short xmodel_airborne; 119 | short xmodel_wehrmacht; 120 | short worldspawn; 121 | short begin; 122 | short dynamite; 123 | short explosive_indicator; 124 | short flamechunk; 125 | short follow; 126 | short free; 127 | short freed; 128 | short func_leaky; 129 | short info_player_checkpoint; 130 | short initialize; 131 | short intermission; 132 | short item_stamina_brandy; 133 | short menuresponse; 134 | short misc_gunner_gun; 135 | short misc_gunner_ring; 136 | short mp_info_player_deathmatch; 137 | short mp_info_player_intermission; 138 | short mp_team_alliedplayer_respawn; 139 | short mp_team_alliedplayer_start; 140 | short mp_team_axisplayer_respawn; 141 | short mp_team_axisplayer_start; 142 | short nail; 143 | short _not; 144 | short playing; 145 | short prox_mine; 146 | short reset; 147 | short script_mover; 148 | short script_multiplayer; 149 | short spear; 150 | short tag_hand; 151 | short tag_rider; 152 | short tag_ring; 153 | short team_CTF_blueflag; 154 | short team_CTF_redflag; 155 | short team_WOLF_checkpoint; 156 | short team_WOLF_objective; 157 | short trigger_aidoor; 158 | short trigger_flagonly; 159 | short trigger_multiple; 160 | short trigger_objective_info; 161 | short waiting_for_players; 162 | short WP; 163 | short zombiespit; 164 | short none; 165 | short dead; 166 | short auto_change; 167 | short manual_change; 168 | } scr_const_t; 169 | 170 | typedef struct { 171 | short texturename; 172 | short contents; 173 | 174 | //assumingly from perk > MAX_PERKS 175 | short perks[MAX_PERKS]; 176 | } xscr_const_t; 177 | 178 | extern xscr_const_t xscr_const; 179 | extern scr_const_t *scr_const; 180 | 181 | /* 182 | A pointer type their variable type is always 7 [object] 183 | */ 184 | 185 | typedef enum { 186 | VT_UNDEFINED, //0 187 | VT_STRING, //1 188 | VT_LOCALIZED_STRING, //2 189 | VT_VECTOR, //3 190 | VT_FLOAT, //4 191 | VT_INT, //5 192 | VT_CODEPOS, //6 193 | VT_OBJECT, //7 194 | VT_KEY_VALUE, //8 195 | VT_FUNCTION, //9 196 | VT_STACK, //10 197 | VT_ANIMATION, //11 198 | VT_THREAD, //12 199 | VT_ENTITY, //13 200 | VT_STRUCT, //14 201 | VT_ARRAY, //16 202 | VT_DEAD_THREAD, //15 203 | VT_DEAD_ENTITY, //17 204 | VT_DEAD_OBJECT //18 205 | } script_variable_type; 206 | 207 | typedef void (__cdecl *SCRIPTFUNCTIONCALL)(int); 208 | 209 | typedef struct { 210 | const char* name; 211 | SCRIPTFUNCTIONCALL call; 212 | int developer; 213 | } SCRIPTFUNCTION; 214 | 215 | typedef SCRIPTFUNCTIONCALL (*Scr_GetFunction_t)(const char**, int*); 216 | typedef SCRIPTFUNCTIONCALL (*Scr_GetMethod_t)(const char**, int*); 217 | 218 | typedef struct { 219 | char *var; 220 | int structure_offset; //Some offset in the state for getting generic fields. 221 | int structure_offset_type; //script type e.g "string", "int" 222 | void (*set)(int); 223 | void (*get)(int); 224 | /* 225 | Under here some additional stuff the CoD structure looks only like the one above. 226 | */ 227 | } scr_memberfield; 228 | 229 | typedef struct { 230 | char *name; 231 | int offset; 232 | int type; 233 | void (*set)(gentity_t*); 234 | } scr_entityfield_t; 235 | 236 | /* 237 | Works just like builtin functions only difference is the assignment or getting part. 238 | e.g instead of 239 | setorigin( org ); 240 | .origin = org; 241 | IF both cases were linked to the same function they'd do the same thing. 242 | this applies for 243 | org = getorigin(); 244 | org = .origin; 245 | 246 | - Richard 247 | */ 248 | 249 | extern Scr_GetFunction_t Scr_GetFunction; 250 | extern Scr_GetMethod_t Scr_GetMethod; 251 | 252 | SCRIPTFUNCTIONCALL Scr_GetCustomFunction(const char**, int*); 253 | SCRIPTFUNCTIONCALL Scr_GetCustomMethod(const char**, int*); 254 | 255 | typedef int (*Scr_GetNumParam_t)(); 256 | typedef int (*Scr_GetPointerType_t)(int); 257 | typedef int (*Scr_GetType_t)(int); 258 | 259 | typedef void (*Scr_MakeArray_t)(); 260 | typedef void (*Scr_AddArray_t)(); 261 | typedef void (*Scr_AddArrayStringIndexed_t)(short); 262 | typedef void (*Scr_Error_t)(const char*); 263 | 264 | typedef int (*Scr_AddFloat_t)(float); 265 | typedef int (*Scr_AddInt_t)(int); 266 | typedef int (*Scr_AddBool_t)(bool); 267 | typedef int (*Scr_AddString_t)(char*); 268 | typedef int (*Scr_AddIString_t)(char*); 269 | typedef int (*Scr_AddVector_t)(vec3_t); 270 | typedef int (*Scr_AddUndefined_t)(); 271 | typedef void (*Scr_AddEntity_t)(int*); 272 | 273 | typedef bool (*Scr_GetBool_t)(int); 274 | typedef int (*Scr_GetInt_t)(int); 275 | typedef void (*Scr_GetAnim_t)(int,int,int); 276 | typedef int (*Scr_GetAnimsIndex_t)(int); 277 | typedef float (*Scr_GetFloat_t)(int); 278 | typedef int (*Scr_GetVector_t)(int, vec3_t); 279 | typedef char* (*Scr_GetString_t)(int); 280 | typedef int (*Scr_GetFunc_t)(int); 281 | typedef short (*Scr_GetOffset_t)(unsigned, const char*); 282 | typedef gentity_t *(*Scr_GetEntity_t)(int); 283 | extern Scr_GetEntity_t Scr_GetEntity; 284 | 285 | typedef int (*Scr_GetConstString_t)(int); 286 | typedef void (*Scr_SetString_t)(int*, unsigned short); 287 | typedef short (*Scr_AllocString_t)(const char*, int); 288 | 289 | typedef int (*oBG_AnimationIndexForString_t)(const char*); 290 | extern oBG_AnimationIndexForString_t oBG_AnimationIndexForString; 291 | 292 | typedef qboolean (*CallSpawnEntity_t)(int); 293 | extern CallSpawnEntity_t CallSpawnEntity; 294 | 295 | extern Scr_AllocString_t Scr_AllocString; 296 | extern Scr_SetString_t Scr_SetString; 297 | extern Scr_GetConstString_t Scr_GetConstString; 298 | 299 | extern Scr_GetNumParam_t Scr_GetNumParam; 300 | extern Scr_GetPointerType_t Scr_GetPointerType; 301 | extern Scr_GetType_t Scr_GetType; 302 | 303 | extern Scr_MakeArray_t Scr_MakeArray; 304 | extern Scr_AddArray_t Scr_AddArray; 305 | extern Scr_AddArrayStringIndexed_t Scr_AddArrayStringIndexed; 306 | extern Scr_Error_t Scr_Error; 307 | 308 | extern Scr_AddInt_t Scr_AddInt; 309 | extern Scr_AddFloat_t Scr_AddFloat; 310 | extern Scr_AddBool_t Scr_AddBool; 311 | extern Scr_AddString_t Scr_AddString; 312 | extern Scr_AddIString_t Scr_AddIString; 313 | extern Scr_AddVector_t Scr_AddVector; 314 | extern Scr_AddUndefined_t Scr_AddUndefined; 315 | extern Scr_AddEntity_t Scr_AddEntity; 316 | 317 | extern Scr_GetBool_t Scr_GetBool; 318 | extern Scr_GetInt_t Scr_GetInt; 319 | extern Scr_GetAnim_t Scr_GetAnim; 320 | extern Scr_GetAnimsIndex_t Scr_GetAnimsIndex; 321 | extern Scr_GetFloat_t Scr_GetFloat; 322 | extern Scr_GetVector_t Scr_GetVector; 323 | extern Scr_GetString_t Scr_GetString; 324 | extern Scr_GetFunc_t Scr_GetFunc; 325 | extern Scr_GetOffset_t Scr_GetOffset; 326 | 327 | typedef int (*Scr_LoadScr_t)(const char*); 328 | typedef int (*Scr_GetFunctionHandle_t)(const char*, const char*); 329 | typedef unsigned short (*Scr_ExecThread_t)(int, int); 330 | typedef unsigned short (*Scr_ExecEntThread_t)(int, int, int, int); 331 | typedef int (*Scr_FreeThread_t)(unsigned short); 332 | 333 | typedef char* (*SL_ConvertToString_t)(unsigned int); 334 | typedef unsigned short (*SL_GetString_t)(const char*, int); 335 | 336 | extern int callbackTest; 337 | extern int callbackPlayerCommand; 338 | extern int callbackRemoteCommand; 339 | extern int callbackFireGrenade; 340 | 341 | extern Scr_LoadScr_t Scr_LoadScript; 342 | extern Scr_GetFunctionHandle_t Scr_GetFunctionHandle; 343 | extern Scr_ExecThread_t Scr_ExecThread; 344 | extern Scr_ExecEntThread_t Scr_ExecEntThread; 345 | extern Scr_FreeThread_t Scr_FreeThread; 346 | extern SL_ConvertToString_t SL_ConvertToString; 347 | extern SL_GetString_t SL_GetString; 348 | 349 | void scriptInitializing(); 350 | char* Scr_GetVariableType(int type); 351 | 352 | /* 353 | ============= 354 | FUNCTIONS 355 | ============= 356 | */ 357 | 358 | void GScr_printconsole(int); 359 | void GScr_Trace(int); 360 | void GScr_trap_Argv(int); 361 | void GScr_ConcatArgs(int); 362 | void GScr_getChat(int); 363 | void GScr_Cmd_Argv(int); 364 | void GScr_Cmd_Argc(int); 365 | void GScr_return(int); 366 | 367 | void GScr_salt_password(int a1); 368 | void GScr_getconfigstring(int); 369 | void GScr_configstringindex(int); 370 | void GScr_system(int); 371 | void GScr_getUnixTime(); 372 | void GScr_strpos(int); 373 | 374 | void GScr_SpawnAnimEnt(int); 375 | void GScr_callspawn(int); 376 | void GScr_GetAnimIndex(int); 377 | 378 | /* 379 | ============= 380 | STRING 381 | ============= 382 | */ 383 | void Scr_StrTok(int); 384 | void Scr_ToLower(int); 385 | void Scr_ToUpper(int); 386 | void Scr_ucfirst(int); 387 | void Scr_replace(int); 388 | void Scr_IsSubStr(int); 389 | void Scr_passArray(int); 390 | void Scr_trim(int); 391 | void Scr_convertToIString(int a1); 392 | 393 | /* 394 | ============= 395 | MATH 396 | ============= 397 | */ 398 | 399 | void MScr_cos(int); 400 | void MScr_sin(int); 401 | void MScr_sqrt(int); 402 | 403 | /* 404 | ===== 405 | BITWISE OPERATORS 406 | ===== 407 | */ 408 | void GScr_and(int); 409 | void GScr_or(int); 410 | void GScr_xor(int); 411 | void GScr_rshift(int); 412 | void GScr_lshift(int); 413 | void GScr_not(int); 414 | 415 | /* 416 | ====== 417 | CRYPTO 418 | ====== 419 | */ 420 | void GScr_md5(int); 421 | 422 | /* 423 | ============= 424 | MYSQL 425 | ============= 426 | */ 427 | #ifdef uMYSQL 428 | void GScr_mysql_init(int); 429 | void GScr_mysql_close(int); 430 | void GScr_mysql_affected_rows(int); 431 | void GScr_mysql_errno(int); 432 | void GScr_mysql_error(int); 433 | void GScr_mysql_fetch_field(int); 434 | void GScr_mysql_fetch_row(int); 435 | void GScr_mysql_field_seek(int); 436 | void GScr_mysql_free_result(int); 437 | void GScr_mysql_num_fields(int); 438 | void GScr_mysql_num_rows(int); 439 | void GScr_mysql_query(int); 440 | void GScr_mysql_real_connect(int); 441 | void GScr_mysql_real_escape_string(int); 442 | void GScr_mysql_store_result(int); 443 | void GScr_mysql_get_connection(int); 444 | #endif 445 | /* 446 | ============= 447 | PLAYER METHODS 448 | ============= 449 | */ 450 | 451 | void PlayerCmd_useButtonPressedX(int); 452 | void PlayerCmd_SetVelocity(int); 453 | void PlayerCmd_GetVelocity(int); 454 | void PlayerCmd_getPlayerAngles(int); 455 | void PlayerCmd_getSpectatorClient(int); 456 | void PlayerCmd_getip(int); 457 | void PlayerCmd_GetInt(int); 458 | void PlayerCmd_SetInt(int); 459 | void PlayerCmd_GetByte(int); 460 | void PlayerCmd_SetByte(int); 461 | void PlayerCmd_GetFloat(int); 462 | void PlayerCmd_SetFloat(int); 463 | void PlayerCmd_GetStance(int); 464 | void PlayerCmd_backButtonPressed(int); 465 | void PlayerCmd_forwardButtonPressed(int); 466 | void PlayerCmd_leftButtonPressed(int); 467 | void PlayerCmd_rightButtonPressed(int); 468 | void PlayerCmd_moveupButtonPressed(int); 469 | void PlayerCmd_movedownButtonPressed(int); 470 | void PlayerCmd_aimButtonPressed(int); 471 | void PlayerCmd_reloadButtonPressed(int); 472 | void PlayerCmd_leanLeftButtonPressed(int); 473 | void PlayerCmd_leanRightButtonPressed(int); 474 | void PlayerCmd_GetUserInfoKey(int); 475 | void PlayerCmd_GetUserInfo(int); 476 | void PlayerCmd_DropClient(int); 477 | void PlayerCmd_kickbot(int); 478 | void PlayerCmd_renamebot(int); 479 | void PlayerCmd_isbot(int); 480 | void PlayerCmd_SendServerCommand(int); 481 | void PlayerCmd_SendGamestate(int); 482 | void PlayerCmd_ispure(int a1); 483 | void PlayerCmd_GetMUID(unsigned); 484 | void PlayerCmd_SetPerk(int); 485 | void PlayerCmd_UnsetPerk(int); 486 | void PlayerCmd_HasPerk(int); 487 | void PlayerCmd_SetMaxSpeed(int); 488 | void PlayerCmd_GetPing(int); 489 | void PlayerCmd_SetMoveSpeedScale(int); 490 | void PlayerCmd_FreezeControls(int); 491 | /* 492 | ============= 493 | ENTITY METHODS 494 | ============= 495 | */ 496 | 497 | void ScriptEnt_SetBounds(int); 498 | void ScriptEnt_SetBoundCorners(int); 499 | void ScriptEnt_SetTakeDamage(int); 500 | void ScriptEnt_SetAbsMax(int); 501 | void ScriptEnt_SetMaxs(int); 502 | void ScriptEnt_SetMins(int); 503 | void ScriptEnt_SetAbsMin(int); 504 | void ScriptEnt_SetLight(int); 505 | void Ent_ShowToPlayer(unsigned num); 506 | 507 | /* 508 | ============= 509 | FILE FUNCTIONS 510 | ============= 511 | */ 512 | 513 | void GScr_fopen(int); 514 | void GScr_fclose(int); 515 | void GScr_fread(int); 516 | void GScr_fexists(int); 517 | void GScr_fsize(int); 518 | void GScr_fwrite(int); 519 | 520 | /* 521 | ============= 522 | MYSQL FUNCTIONS 523 | ============= 524 | */ 525 | 526 | #ifdef uMYSQL 527 | 528 | void GScr_mysql_init(int); 529 | void GScr_mysql_close(int); 530 | void GScr_mysql_affected_rows(int); 531 | void GScr_mysql_errno(int); 532 | void GScr_mysql_error(int); 533 | void GScr_mysql_fetch_field(int); 534 | void GScr_mysql_field_seek(int); 535 | void GScr_mysql_free_result(int); 536 | void GScr_mysql_num_fields(int); 537 | void GScr_mysql_num_rows(int); 538 | void GScr_mysql_query(int); 539 | void GScr_mysql_real_connect(int); 540 | void GScr_mysql_real_escape_string(int); 541 | void GScr_mysql_store_result(int); 542 | 543 | #endif //uMYSQL 544 | 545 | #endif // SCRIPT_H -------------------------------------------------------------------------------- /src/server.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #ifndef SERVER_H 19 | #define SERVER_H 20 | 21 | /* 22 | Still not quite happy with the including of some files. 23 | //richard 24 | */ 25 | 26 | #include "shared.h" 27 | #include "script.h" 28 | #include 29 | 30 | #if CODPATCH == 1 31 | #define svsclients_ptr 0x83B67AC 32 | #define clientsize 370940 33 | #else 34 | #define svsclients_ptr 0x83CCD90 35 | #define clientsize 371124 36 | #endif 37 | 38 | #define SVF_NOCLIENT 0x00000001 39 | #define SVF_BROADCAST 0x00000020 40 | #define SVF_CAPSULE 0x00000200 // use capsule for collision detection 41 | #define SVF_SINGLECLIENT 0x00000800 // only send to a single client (entityShared_t->singleClient) 42 | #define SVF_NOTSINGLECLIENT 0x00002000 // send entity to everyone but one client 43 | 44 | #if CODPATCH == 1 45 | #define svs_time (*(int*)0x83B67A4) 46 | #else if CODPATCH == 5 47 | #define svs_time (*(int*)0x83CCD88) 48 | #endif 49 | 50 | extern int clientversion; 51 | 52 | typedef enum { 53 | svc_bad, 54 | svc_nop, 55 | svc_gamestate, 56 | svc_configstring, // [short] [string] only in gamestate messages 57 | svc_baseline, // only in gamestate messages 58 | svc_serverCommand, // [string] to be executed by client game module 59 | svc_download, // [short] size [size bytes] 60 | svc_snapshot, 61 | svc_EOF 62 | } svc_ops_e; //not really server only it's for client aswell 63 | 64 | static char *svc_strings[256] = { 65 | "svc_bad", 66 | "svc_nop", 67 | "svc_gamestate", 68 | "svc_configstring", 69 | "svc_baseline", 70 | "svc_serverCommand", 71 | "svc_download", 72 | "svc_snapshot", 73 | "svc_EOF" 74 | }; 75 | 76 | typedef enum { 77 | NA_BOT, 78 | NA_BAD, // an address lookup failed 79 | NA_LOOPBACK, 80 | NA_BROADCAST, 81 | NA_IP, 82 | NA_IPX, 83 | NA_BROADCAST_IPX 84 | } netadrtype_t; 85 | 86 | typedef enum { 87 | NS_CLIENT, 88 | NS_SERVER 89 | } netsrc_t; 90 | 91 | typedef struct { 92 | netadrtype_t type; 93 | union { 94 | byte ip[4]; 95 | unsigned int _ip; 96 | }; 97 | byte ipx[10]; 98 | 99 | unsigned short port; 100 | } netadr_t; //size = 0x14 (20) 101 | 102 | typedef enum { 103 | MUIDBAN, 104 | IPBAN 105 | } ban_types; 106 | 107 | typedef struct { 108 | int type; //ban_types 109 | char mUID[33]; 110 | netadr_t adr; 111 | char reason[128]; 112 | } banInfo_t; 113 | 114 | extern LinkedList banlist; 115 | 116 | extern char x_mastername[14]; 117 | extern netadr_t x_master; 118 | 119 | #define MAX_CHALLENGES 1024 120 | 121 | typedef struct { 122 | netadr_t adr; //0 123 | int challenge; //20 124 | int time; //24 125 | int pingTime; //28 126 | int firstTime; //32 127 | int firstPing; //36 128 | int connected; //40 129 | #if CODPATCH == 5 130 | int guid; //44 131 | unsigned char __idk[36]; 132 | #endif 133 | } challenge_t; 134 | 135 | typedef struct { 136 | int idk33[4]; 137 | int svFlags; 138 | int singleClient; 139 | char pad[256]; 140 | int idk; 141 | } entityShared_t; 142 | 143 | typedef struct { 144 | entityState_t s; 145 | entityShared_t r; 146 | } sharedEntity_t; 147 | 148 | typedef sharedEntity_t* (*SV_GentityNum_t)( int num ); 149 | extern SV_GentityNum_t SV_GentityNum; 150 | 151 | typedef void (*SV_SetConfigstring_t)( int index, const char *val ); 152 | typedef void (*SV_GetConfigstring_t)( int index, char *buffer, int bufferSize ); 153 | extern SV_GetConfigstring_t SV_GetConfigstring; 154 | extern SV_SetConfigstring_t SV_SetConfigstring; 155 | 156 | 157 | void SV_GetChallenge( netadr_t* from ); 158 | void SV_Init( void ); 159 | void SV_DirectConnect( netadr_t from ); 160 | void SV_AuthorizeIpPacket( netadr_t from ); 161 | 162 | void SV_MasterHeartBeat(const char*); 163 | 164 | extern cvar_t *sv_maxclients; 165 | extern cvar_t *sv_privateClients; 166 | extern cvar_t *g_gametype; 167 | extern cvar_t *mapname; 168 | extern cvar_t *sv_hostname; 169 | extern cvar_t *sv_maxRate; 170 | extern cvar_t *sv_maxPing; 171 | extern cvar_t *sv_minPing; 172 | extern cvar_t *sv_floodProtect; 173 | extern cvar_t *sv_allowAnonymous; 174 | extern cvar_t *sv_showCommands; 175 | extern cvar_t *sv_pure; 176 | extern cvar_t *sv_serverid; 177 | extern cvar_t *rconPassword; 178 | extern cvar_t *sv_privatePassword; 179 | extern cvar_t *sv_fps; 180 | extern cvar_t *sv_timeout; 181 | extern cvar_t *sv_zombietime; 182 | extern cvar_t *sv_allowDownload; 183 | extern cvar_t *sv_master1; 184 | extern cvar_t *sv_master2; 185 | extern cvar_t *sv_master3; 186 | extern cvar_t *sv_master4; 187 | extern cvar_t *sv_master5; 188 | extern cvar_t *sv_reconnectlimit; 189 | extern cvar_t *sv_showloss; 190 | extern cvar_t *sv_padPackets; 191 | extern cvar_t *sv_killserver; 192 | extern cvar_t *sv_onlyVisibleClients; 193 | extern cvar_t *sv_showAverageBPS; 194 | extern cvar_t *sv_mapRotation; 195 | extern cvar_t *sv_mapRotationCurrent; 196 | extern cvar_t *shortversion; 197 | extern cvar_t *protocol; 198 | extern cvar_t* dedicated; 199 | extern cvar_t* sv_running; 200 | 201 | #if CODPATCH == 5 202 | extern cvar_t *sv_disableClientConsole; 203 | #endif 204 | 205 | extern cvar_t *x_globalbans; 206 | extern cvar_t *x_bannedmessage; 207 | extern cvar_t *x_contents; 208 | extern cvar_t *x_stuck; 209 | extern cvar_t *x_deadchat; 210 | extern cvar_t *x_authorize; 211 | extern cvar_t *x_spectator_noclip; 212 | extern cvar_t *x_connectmessage; 213 | 214 | extern cvar_t *cl_allowDownload; //the client will locally change any cvars to match the SYSTEMINFO cvars 215 | 216 | #define MAX_MASTER_SERVERS 5 217 | extern cvar_t* sv_master[MAX_MASTER_SERVERS]; 218 | 219 | extern char x_print_connect_message[1024]; 220 | extern char SVC_CHANDELIER[12]; 221 | 222 | typedef void (QDECL *NET_OutOfBandPrint_t)( netsrc_t net_socket, netadr_t adr, const char *format, ... ); 223 | extern NET_OutOfBandPrint_t NET_OutOfBandPrint; 224 | 225 | typedef qboolean (*NET_StringToAdr_t)( const char *s, netadr_t *a ); 226 | extern NET_StringToAdr_t NET_StringToAdr; 227 | 228 | const char *NET_BaseAdrToString (netadr_t a); 229 | const char *NET_AdrToString (netadr_t a); 230 | qboolean NET_CompareAdr( netadr_t a, netadr_t b ); 231 | qboolean NET_CompareBaseAdr( netadr_t a, netadr_t b ); 232 | bool NET_IsLocalAddress( netadr_t adr ); 233 | 234 | typedef void (*NET_SendPacket_t)( netsrc_t sock, int length, const void *data, netadr_t to ); 235 | extern NET_SendPacket_t NET_SendPacket; 236 | 237 | //void QDECL NET_OutOfBandPrint( netsrc_t sock, netadr_t adr, const char *format, ... ); 238 | 239 | extern netadr_t authorizeAddress; 240 | extern netadr_t masterAddress; 241 | 242 | typedef enum { 243 | CS_FREE, // can be reused for a new connection 244 | CS_ZOMBIE, // client has been disconnected, but don't reuse connection for a couple seconds 245 | CS_CONNECTED, // has been assigned to a client_t, but no gamestate yet 246 | CS_PRIMED, // gamestate has been sent, but client hasn't sent a usercmd 247 | CS_ACTIVE // client is fully in game 248 | } clientState_t; 249 | 250 | typedef struct { //usercmd_s i defined in server.h mmmmmmm 251 | playerState_t *ps; 252 | usercmd_t cmd; 253 | //other stuff 254 | } pmove_t; 255 | 256 | extern pmove_t *pm; 257 | 258 | #define iprintln(m) SV_SendServerCommand(NULL, 0, "e \"%s\"", m) 259 | 260 | typedef struct { 261 | netsrc_t sock; 262 | int dropped; 263 | netadr_t remoteAddress; 264 | int qport; 265 | /* lot more bs here */ 266 | } netchan_t; 267 | 268 | typedef struct client_s { 269 | int state; 270 | int unknown4; 271 | int unknown8; 272 | char userinfo[1024]; 273 | char field_40C; 274 | char gap_40D[66047]; 275 | int reliableSequence; 276 | int reliableAcknowledge; 277 | char gap_10614; 278 | char gap_10615[7]; 279 | int gamestateMessageNum; 280 | int challenge; 281 | usercmd_t lastUsercmd; 282 | int lastClientCommand; 283 | char lastClientCommandString[1024]; 284 | unsigned int gentity; 285 | char name[32]; 286 | char downloadName[64]; 287 | int download; 288 | int downloadSize; 289 | int downloadCount; 290 | int junk; 291 | int gap_10AB4; 292 | char gap_10AB8[84]; 293 | int lastPacketTime; 294 | int lastConnectTime; 295 | int nextSnapshotTime; 296 | char gap_10B18[269704]; 297 | int ping; 298 | int rate; 299 | int snapshotMsec; 300 | int pureAuthentic; 301 | netchan_t netchan; 302 | char lazy_to_figure_out_so_fill_it_up[32812]; 303 | } client_t; 304 | 305 | 306 | typedef void (*Netchan_Setup_t)( netsrc_t sock, netchan_t* chan, netadr_t adr, int qport ); 307 | extern Netchan_Setup_t Netchan_Setup; 308 | 309 | typedef struct animation_s { 310 | char name[64]; //pb_combatwalk_left_loop_pistol 311 | int a; //4294967295 312 | int b; //31 313 | int c; //733 314 | int d; //426038 315 | int e; //144 316 | int f; //16 317 | int g; //0 318 | } animation_t; 319 | 320 | /* 321 | from 1.5 322 | 323 | typedef enum { 324 | UCMD_BUTTONS = 8, //for messagemode/console, cl_run (+speed) (aim down the sight) 325 | UCMD_WBUTTONS, //+reload, +leanright +leanleft 326 | UCMD_FORWARDMOVE = 23, 327 | UCMD_RIGHTMOVE, 328 | UCMD_UPMOVE 329 | } usercmd_offset; 330 | 331 | 332 | typedef struct usercmd_s { 333 | int serverTime; 334 | byte buttons; 335 | byte wbuttons; 336 | byte weapon; 337 | byte flags; 338 | byte unknown1[13]; 339 | / * 340 | forward = 127 341 | back = 129 342 | right = 127 343 | left = 129 344 | up = 127 345 | prone = 129 346 | * / 347 | signed char forwardmove, rightmove, upmove; 348 | byte doubleTap; // Arnout: only 3 bits used 349 | 350 | // rain - in ET, this can be any entity, and it's used as an array 351 | // index, so make sure it's unsigned 352 | byte identClient; // NERVE - SMF 353 | } usercmd_t; 354 | */ 355 | 356 | typedef struct { 357 | char mUID[33]; 358 | 359 | long long chattimer; 360 | long long commandtimer; 361 | int uid; 362 | bool pure; 363 | int clientusage; 364 | 365 | qboolean namemuted; //can this player rename? 366 | qboolean muted; //can this player chat? 367 | 368 | int perks[MAX_PERKS]; 369 | int sprinting; 370 | } xtnded_client, x_client; 371 | 372 | #define xclient_t x_client 373 | 374 | typedef struct { 375 | /*extended info for the challenges */ 376 | #if 0 //kinda unneeded 377 | netadr_t adr; 378 | int challenge; 379 | int time; 380 | #endif 381 | int guid; 382 | char mUID[33]; 383 | int bCanConnect; 384 | bool bAuthRequested; 385 | time_t msgtime; 386 | } x_challenge; 387 | 388 | extern x_challenge x_challenges[MAX_CHALLENGES]; 389 | extern xtnded_client xtnded_clients[64]; 390 | 391 | 392 | #define clearchallenge(i) \ 393 | memset( &challenges[i], 0, sizeof( challenges[i] ) ); \ 394 | memset( &x_challenges[i], 0, sizeof( x_challenges[i] ) ) 395 | 396 | #define x_clients xtnded_clients 397 | #define xclients x_clients 398 | 399 | extern client_t** clients; 400 | 401 | extern cvar_t *sv_maxclients; 402 | 403 | extern challenge_t* challenges; 404 | 405 | /* 406 | x commands 407 | */ 408 | 409 | void Cmd_CallVote(unsigned); 410 | 411 | typedef void (__cdecl *SV_StopDownload_f_t)(client_t*); 412 | extern SV_StopDownload_f_t SV_StopDownload_f; 413 | 414 | typedef void (*SV_BeginDownload_f_t)(client_t*); 415 | extern SV_BeginDownload_f_t SV_BeginDownload_f; 416 | 417 | typedef void (*SV_DropClient_t)(client_t*, const char* reason); 418 | extern SV_DropClient_t SV_DropClient; 419 | 420 | typedef void (*SV_FreeClientScriptId_t)(client_t*); 421 | extern SV_FreeClientScriptId_t SV_FreeClientScriptId; 422 | 423 | typedef int (*SV_GetClientScore_t)(client_t*); 424 | extern SV_GetClientScore_t SV_GetClientScore; 425 | 426 | void SV_Status_f(); 427 | void SV_UserinfoChanged( client_t* cl ); 428 | 429 | #define SHOWMSG_MSEC 2050 430 | 431 | client_t* getclient(int); 432 | char *ConcatArgs( int start ); 433 | typedef void (*SV_Trace_t)( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); 434 | typedef void (QDECL *SV_SendServerCommand_t)(client_t*, int, const char*, ...); //actually is gamesendservercommand which then checks and then calls sendservercommand 435 | typedef void (*getuserinfo_t)( int index, char *buffer, int bufferSize ); 436 | typedef void (*setuserinfo_t)(int,const char*); 437 | extern SV_Trace_t SV_Trace; 438 | extern SV_SendServerCommand_t SV_SendServerCommand; 439 | extern getuserinfo_t getuserinfo; 440 | extern setuserinfo_t setuserinfo; 441 | 442 | // RATELIMITER (experimental) 443 | unsigned long sys_timeBase; 444 | int curtime; 445 | int Sys_Milliseconds(void); 446 | typedef struct leakyBucket_s leakyBucket_t; 447 | struct leakyBucket_s 448 | { 449 | netadrtype_t type; 450 | unsigned char _4[4]; 451 | int lastTime; 452 | signed char burst; 453 | long hash; 454 | 455 | leakyBucket_t *prev, *next; 456 | }; 457 | #define MAX_BUCKETS 16384 458 | #define MAX_HASHES 1024 459 | static leakyBucket_t buckets[MAX_BUCKETS]; 460 | static leakyBucket_t *bucketHashes[MAX_HASHES]; 461 | leakyBucket_t outboundLeakyBucket; 462 | static long SVC_HashForAddress(netadr_t address); 463 | static leakyBucket_t *SVC_BucketForAddress(netadr_t address, int burst, int period); 464 | bool SVC_RateLimit(leakyBucket_t *bucket, int burst, int period); 465 | bool SVC_RateLimitAddress(netadr_t from, int burst, int period); 466 | 467 | #endif // SERVER_H 468 | -------------------------------------------------------------------------------- /src/shared.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "shared.h" 19 | 20 | xentity_t xentities[1024]; 21 | 22 | void* gamelib; 23 | int base; 24 | char (*pml)[140]; 25 | 26 | level_locals_t *level; 27 | 28 | gentity_t *g_entities; 29 | 30 | char* modNames[] = { 31 | "MOD_UNKNOWN", 32 | "MOD_PISTOL_BULLET", 33 | "MOD_RIFLE_BULLET", 34 | "MOD_GRENADE", 35 | "MOD_GRENADE_SPLASH", 36 | "MOD_PROJECTILE", 37 | "MOD_PROJECTILE_SPLASH", 38 | "MOD_MELEE", 39 | "MOD_HEAD_SHOT", 40 | "MOD_MORTAR", 41 | "MOD_MORTAR_SPLASH", 42 | "MOD_KICKED", 43 | "MOD_GRABBER", 44 | "MOD_DYNAMITE", 45 | "MOD_DYNAMITE_SPLASH", 46 | "MOD_AIRSTRIKE", 47 | "MOD_WATER", 48 | "MOD_SLIME", 49 | "MOD_LAVA", 50 | "MOD_CRUSH", 51 | "MOD_TELEFRAG", 52 | "MOD_FALLING", 53 | "MOD_SUICIDE", 54 | "MOD_TRIGGER_HURT", 55 | "MOD_EXPLOSIVE" 56 | }; 57 | 58 | #if CODPATCH == 1 59 | _Cmd_AddCommand_t _Cmd_AddCommand = (_Cmd_AddCommand_t)0x805AEF8; 60 | //Com_Printf_t _STRIP Com_Printf = (Com_Printf_t)0x806B760; 61 | DECLARE_F(Com_Printf, 0x806B760); 62 | Com_DPrintf_t _STRIP Com_DPrintf = (Com_DPrintf_t)0x806B79C; 63 | Com_Error_t _STRIP Com_Error = (Com_Error_t)0x806B93C; 64 | Cmd_Argv_t Cmd_Argv = (Cmd_Argv_t)0x805B258; 65 | Cmd_Argc_t Cmd_Argc = (Cmd_Argc_t)0x805B24C; 66 | Cmd_ArgvBuffer_t Cmd_ArgvBuffer = (Cmd_ArgvBuffer_t)0x805B27C; 67 | Cmd_TokenizeString_t Cmd_TokenizeString = (Cmd_TokenizeString_t)0x805B398; 68 | VM_Call_t VM_Call = (VM_Call_t)0x8092158; 69 | #else 70 | _Cmd_AddCommand_t _Cmd_AddCommand = (_Cmd_AddCommand_t)0x806043E; 71 | Com_Printf_t Com_Printf = (Com_Printf_t)0x806FC10; 72 | Com_DPrintf_t Com_DPrintf = (Com_DPrintf_t)0x806FC5F; 73 | Com_Error_t Com_Error = (Com_Error_t)0x806FE74; 74 | Cmd_Argv_t Cmd_Argv = (Cmd_Argv_t)0x80600F4; 75 | Cmd_Argc_t Cmd_Argc = (Cmd_Argc_t)0x80600EA; 76 | Cmd_ArgvBuffer_t Cmd_ArgvBuffer = (Cmd_ArgvBuffer_t)0x806014B; 77 | Cmd_TokenizeString_t Cmd_TokenizeString = (Cmd_TokenizeString_t)0x8060423; 78 | 79 | VM_Call_t VM_Call = (VM_Call_t)0x809AFBC; 80 | #endif 81 | 82 | //Info_SetValueForKey_t Info_SetValueForKey = (Info_SetValueForKey_t)0x80827D4; 83 | 84 | //============================================================================ 85 | /* 86 | ================== 87 | COM_BitCheck 88 | 89 | Allows bit-wise checks on arrays with more than one item (> 32 bits) 90 | ================== 91 | */ 92 | qboolean COM_BitCheck( const int array[], int bitNum ) { 93 | int i; 94 | 95 | i = 0; 96 | while ( bitNum > 31 ) { 97 | i++; 98 | bitNum -= 32; 99 | } 100 | 101 | return ( ( array[i] & ( 1 << bitNum ) ) != 0 ); // (SA) heh, whoops. :) 102 | } 103 | 104 | /* 105 | ================== 106 | COM_BitSet 107 | 108 | Allows bit-wise SETS on arrays with more than one item (> 32 bits) 109 | ================== 110 | */ 111 | void COM_BitSet( int array[], int bitNum ) { 112 | int i; 113 | 114 | i = 0; 115 | while ( bitNum > 31 ) { 116 | i++; 117 | bitNum -= 32; 118 | } 119 | 120 | array[i] |= ( 1 << bitNum ); 121 | } 122 | 123 | /* 124 | ================== 125 | COM_BitClear 126 | 127 | Allows bit-wise CLEAR on arrays with more than one item (> 32 bits) 128 | ================== 129 | */ 130 | void COM_BitClear( int array[], int bitNum ) { 131 | int i; 132 | 133 | i = 0; 134 | while ( bitNum > 31 ) { 135 | i++; 136 | bitNum -= 32; 137 | } 138 | 139 | array[i] &= ~( 1 << bitNum ); 140 | } 141 | 142 | /* 143 | ============================================================================ 144 | 145 | LIBRARY REPLACEMENT FUNCTIONS 146 | 147 | ============================================================================ 148 | */ 149 | 150 | int _STRIP Q_isprint( int c ) { 151 | if ( c >= 0x20 && c <= 0x7E ) { 152 | return ( 1 ); 153 | } 154 | return ( 0 ); 155 | } 156 | 157 | int _STRIP Q_islower( int c ) { 158 | if ( c >= 'a' && c <= 'z' ) { 159 | return ( 1 ); 160 | } 161 | return ( 0 ); 162 | } 163 | 164 | int _STRIP Q_isupper( int c ) { 165 | if ( c >= 'A' && c <= 'Z' ) { 166 | return ( 1 ); 167 | } 168 | return ( 0 ); 169 | } 170 | 171 | int _STRIP Q_isalpha( int c ) { 172 | if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ) { 173 | return ( 1 ); 174 | } 175 | return ( 0 ); 176 | } 177 | 178 | int _STRIP Q_isnumeric( int c ) { 179 | if ( c >= '0' && c <= '9' ) { 180 | return ( 1 ); 181 | } 182 | return ( 0 ); 183 | } 184 | 185 | int _STRIP Q_isalphanumeric( int c ) { 186 | if ( Q_isalpha( c ) || 187 | Q_isnumeric( c ) ) { 188 | return( 1 ); 189 | } 190 | return ( 0 ); 191 | } 192 | 193 | int _STRIP Q_isforfilename( int c ) { 194 | if ( ( Q_isalphanumeric( c ) || c == '_' ) && c != ' ' ) { // space not allowed in filename 195 | return( 1 ); 196 | } 197 | return ( 0 ); 198 | } 199 | 200 | char* _STRIP Q_strrchr( const char* string, int c ) { 201 | char cc = c; 202 | char *s; 203 | char *sp = (char *)0; 204 | 205 | s = (char*)string; 206 | 207 | while ( *s ) 208 | { 209 | if ( *s == cc ) { 210 | sp = s; 211 | } 212 | s++; 213 | } 214 | if ( cc == 0 ) { 215 | sp = s; 216 | } 217 | 218 | return sp; 219 | } 220 | 221 | /* 222 | ============= 223 | Q_strncpyz 224 | 225 | Safe strncpy that ensures a trailing zero 226 | ============= 227 | */ 228 | void _STRIP Q_strncpyz( char *dest, const char *src, int destsize ) { 229 | if ( !src ) { 230 | Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" ); 231 | } 232 | if ( destsize < 1 ) { 233 | Com_Error( ERR_FATAL,"Q_strncpyz: destsize < 1" ); 234 | } 235 | 236 | strncpy( dest, src, destsize - 1 ); 237 | dest[destsize - 1] = 0; 238 | } 239 | 240 | const char* _STRIP Q_stristr( const char *s, const char *find) { 241 | register char c, sc; 242 | register size_t len; 243 | 244 | if ((c = *find++) != 0) 245 | { 246 | if (c >= 'a' && c <= 'z') 247 | { 248 | c -= ('a' - 'A'); 249 | } 250 | len = strlen(find); 251 | do 252 | { 253 | do 254 | { 255 | if ((sc = *s++) == 0) 256 | return NULL; 257 | if (sc >= 'a' && sc <= 'z') 258 | { 259 | sc -= ('a' - 'A'); 260 | } 261 | } while (sc != c); 262 | } while (Q_stricmpn(s, find, len) != 0); 263 | s--; 264 | } 265 | return s; 266 | } 267 | 268 | int _STRIP stricmp (const char *p1, const char *p2) 269 | { 270 | register unsigned char *s1 = (unsigned char *) p1; 271 | register unsigned char *s2 = (unsigned char *) p2; 272 | unsigned char c1, c2; 273 | 274 | do 275 | { 276 | c1 = (unsigned char) toupper((int)*s1++); 277 | c2 = (unsigned char) toupper((int)*s2++); 278 | if (c1 == '\0') 279 | { 280 | return c1 - c2; 281 | } 282 | } 283 | while (c1 == c2); 284 | 285 | return c1 - c2; 286 | } 287 | 288 | void _STRIP Com_sprintf( char *dest, int size, const char *fmt, ... ) { 289 | int ret; 290 | va_list argptr; 291 | 292 | va_start( argptr,fmt ); 293 | ret = vsnprintf( dest, size, fmt, argptr ); //Q_vsnprintf 294 | va_end( argptr ); 295 | if ( ret == -1 ) { 296 | printf( "Com_sprintf: overflow of %i bytes buffer\n", size ); 297 | } 298 | } 299 | 300 | #define Q_COLOR_ESCAPE '^' 301 | #define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) 302 | 303 | char * _STRIP Q_CleanStr( char *string ) { 304 | char* d; 305 | char* s; 306 | int c; 307 | 308 | s = string; 309 | d = string; 310 | while ( ( c = *s ) != 0 ) { 311 | if ( Q_IsColorString( s ) ) { 312 | s++; 313 | } else if ( c >= 0x20 && c <= 0x7E ) { 314 | *d++ = c; 315 | } 316 | s++; 317 | } 318 | *d = '\0'; 319 | 320 | return string; 321 | } 322 | 323 | void _STRIP Info_Print( const char *s ) { 324 | char key[512]; 325 | char value[512]; 326 | char *o; 327 | int l; 328 | 329 | if ( *s == '\\' ) { 330 | s++; 331 | } 332 | while ( *s ) 333 | { 334 | o = key; 335 | while ( *s && *s != '\\' ) 336 | *o++ = *s++; 337 | 338 | l = o - key; 339 | if ( l < 20 ) { 340 | memset( o, ' ', 20 - l ); 341 | key[20] = 0; 342 | } else { 343 | *o = 0; 344 | } 345 | Com_Printf( "%s", key ); 346 | 347 | if ( !*s ) { 348 | Com_Printf( "MISSING VALUE\n" ); 349 | return; 350 | } 351 | 352 | o = value; 353 | s++; 354 | while ( *s && *s != '\\' ) 355 | *o++ = *s++; 356 | *o = 0; 357 | 358 | if ( *s ) { 359 | s++; 360 | } 361 | Com_Printf( "%s\n", value ); 362 | } 363 | } 364 | 365 | /* 366 | =============== 367 | Info_ValueForKey 368 | 369 | Searches the string for the given 370 | key and returns the associated value, or an empty string. 371 | FIXME: overflow check? 372 | =============== 373 | */ 374 | char* _STRIP Info_ValueForKey( const char *s, const char *key ) { 375 | char pkey[BIG_INFO_KEY]; 376 | static char value[2][BIG_INFO_VALUE]; // use two buffers so compares 377 | // work without stomping on each other 378 | static int valueindex = 0; 379 | char *o; 380 | 381 | if ( !s || !key ) { 382 | return ""; 383 | } 384 | 385 | if ( strlen( s ) >= BIG_INFO_STRING ) { 386 | Com_Error(ERR_FATAL, "Info_ValueForKey: oversize infostring [%s] [%s]", s, key ); 387 | } 388 | 389 | valueindex ^= 1; 390 | if ( *s == '\\' ) { 391 | s++; 392 | } 393 | while ( 1 ) 394 | { 395 | o = pkey; 396 | while ( *s != '\\' ) 397 | { 398 | if ( !*s ) { 399 | return ""; 400 | } 401 | *o++ = *s++; 402 | } 403 | *o = 0; 404 | s++; 405 | 406 | o = value[valueindex]; 407 | 408 | while ( *s != '\\' && *s ) 409 | { 410 | *o++ = *s++; 411 | } 412 | *o = 0; 413 | 414 | if ( !stricmp( key, pkey ) ) { 415 | return value[valueindex]; 416 | } 417 | 418 | if ( !*s ) { 419 | break; 420 | } 421 | s++; 422 | } 423 | 424 | return ""; 425 | } 426 | 427 | /* 428 | =================== 429 | Info_RemoveKey 430 | =================== 431 | */ 432 | void _STRIP Info_RemoveKey( char *s, const char *key ) { 433 | char *start; 434 | char pkey[MAX_INFO_KEY]; 435 | char value[MAX_INFO_VALUE]; 436 | char *o; 437 | 438 | if ( strlen( s ) >= MAX_INFO_STRING ) { 439 | Com_Error( ERR_DROP, "Info_RemoveKey: oversize infostring [%s] [%s]", s, key ); 440 | return; 441 | } 442 | 443 | if ( strchr( key, '\\' ) ) { 444 | return; 445 | } 446 | 447 | while ( 1 ) 448 | { 449 | start = s; 450 | if ( *s == '\\' ) { 451 | s++; 452 | } 453 | o = pkey; 454 | while ( *s != '\\' ) 455 | { 456 | if ( !*s ) { 457 | return; 458 | } 459 | *o++ = *s++; 460 | } 461 | *o = 0; 462 | s++; 463 | 464 | o = value; 465 | while ( *s != '\\' && *s ) 466 | { 467 | if ( !*s ) { 468 | return; 469 | } 470 | *o++ = *s++; 471 | } 472 | *o = 0; 473 | 474 | if ( !Q_stricmp( key, pkey ) ) { 475 | // rain - arguments to strcpy must not overlap 476 | //strcpy (start, s); // remove this part 477 | memmove( start, s, strlen( s ) + 1 ); // remove this part 478 | return; 479 | } 480 | 481 | if ( !*s ) { 482 | return; 483 | } 484 | } 485 | 486 | } 487 | 488 | /* 489 | ================== 490 | Info_SetValueForKey 491 | 492 | Changes or adds a key/value pair 493 | ================== 494 | */ 495 | void _STRIP Info_SetValueForKey( char *s, const char *key, const char *value ) { 496 | char newi[MAX_INFO_STRING]; 497 | 498 | if ( strlen( s ) >= MAX_INFO_STRING ) { 499 | Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring [%s] [%s] [%s]", s, key, value ); 500 | return; 501 | } 502 | 503 | if ( strchr( key, '\\' ) || strchr( value, '\\' ) ) { 504 | printf( "Can't use keys or values with a \\\n" ); 505 | return; 506 | } 507 | 508 | if ( strchr( key, ';' ) || strchr( value, ';' ) ) { 509 | printf( "Can't use keys or values with a semicolon\n" ); 510 | return; 511 | } 512 | 513 | if ( strchr( key, '\"' ) || strchr( value, '\"' ) ) { 514 | printf( "Can't use keys or values with a \"\n" ); 515 | return; 516 | } 517 | 518 | Info_RemoveKey( s, key ); 519 | if ( !value || !strlen( value ) ) { 520 | return; 521 | } 522 | 523 | Com_sprintf( newi, sizeof( newi ), "\\%s\\%s", key, value ); 524 | 525 | if ( strlen( newi ) + strlen( s ) > MAX_INFO_STRING ) { 526 | printf( "Info string length exceeded\n" ); 527 | return; 528 | } 529 | 530 | strcat( s, newi ); 531 | } 532 | 533 | int _STRIP Q_stricmpn( const char *s1, const char *s2, int n ) { 534 | int c1, c2; 535 | 536 | do { 537 | c1 = *s1++; 538 | c2 = *s2++; 539 | 540 | if ( !n-- ) { 541 | return 0; // strings are equal until end point 542 | } 543 | 544 | if ( c1 != c2 ) { 545 | if ( c1 >= 'a' && c1 <= 'z' ) { 546 | c1 -= ( 'a' - 'A' ); 547 | } 548 | if ( c2 >= 'a' && c2 <= 'z' ) { 549 | c2 -= ( 'a' - 'A' ); 550 | } 551 | if ( c1 != c2 ) { 552 | return c1 < c2 ? -1 : 1; 553 | } 554 | } 555 | } while ( c1 ); 556 | 557 | return 0; // strings are equal 558 | } 559 | 560 | int _STRIP Q_strncmp( const char *s1, const char *s2, int n ) { 561 | int c1, c2; 562 | 563 | do { 564 | c1 = *s1++; 565 | c2 = *s2++; 566 | 567 | if ( !n-- ) { 568 | return 0; // strings are equal until end point 569 | } 570 | 571 | if ( c1 != c2 ) { 572 | return c1 < c2 ? -1 : 1; 573 | } 574 | } while ( c1 ); 575 | 576 | return 0; // strings are equal 577 | } 578 | 579 | int _STRIP Q_stricmp( const char *s1, const char *s2 ) { 580 | return ( s1 && s2 ) ? Q_stricmpn( s1, s2, 99999 ) : -1; 581 | } 582 | 583 | char *Q_strlwr( char *s1 ) { 584 | char* s; 585 | 586 | for ( s = s1; *s; ++s ) { 587 | if ( ( 'A' <= *s ) && ( *s <= 'Z' ) ) { 588 | *s -= 'A' - 'a'; 589 | } 590 | } 591 | 592 | return s1; 593 | } 594 | 595 | char _STRIP *Q_strupr( char *s1 ) { 596 | char* cp; 597 | 598 | for ( cp = s1 ; *cp ; ++cp ) { 599 | if ( ( 'a' <= *cp ) && ( *cp <= 'z' ) ) { 600 | *cp += 'A' - 'a'; 601 | } 602 | } 603 | 604 | return s1; 605 | } 606 | 607 | 608 | // never goes past bounds or leaves without a terminating 0 609 | void _STRIP Q_strcat( char *dest, int size, const char *src ) { 610 | int l1; 611 | 612 | l1 = strlen( dest ); 613 | if ( l1 >= size ) { 614 | Com_Error( ERR_FATAL, "Q_strcat: already overflowed" ); 615 | } 616 | Q_strncpyz( dest + l1, src, size - l1 ); 617 | } 618 | 619 | /* 620 | ============ 621 | va 622 | 623 | does a varargs printf into a temp buffer, so I don't need to have 624 | varargs versions of all text functions. 625 | FIXME: make this buffer size safe someday 626 | 627 | Ridah, modified this into a circular list, to further prevent stepping on 628 | previous strings 629 | ============ 630 | */ 631 | 632 | char * _STRIP QDECL va( char *format, ... ) { 633 | va_list argptr; 634 | #define MAX_VA_STRING 32000 635 | static char temp_buffer[MAX_VA_STRING]; 636 | static char string[MAX_VA_STRING]; // in case va is called by nested functions 637 | static int index = 0; 638 | char *buf; 639 | int len; 640 | 641 | 642 | va_start( argptr, format ); 643 | vsprintf( temp_buffer, format,argptr ); 644 | va_end( argptr ); 645 | 646 | if ( ( len = strlen( temp_buffer ) ) >= MAX_VA_STRING ) { 647 | Com_Error( ERR_DROP, "Attempted to overrun string in call to va()\n" ); 648 | } 649 | 650 | if ( len + index >= MAX_VA_STRING - 1 ) { 651 | index = 0; 652 | } 653 | 654 | buf = &string[index]; 655 | memcpy( buf, temp_buffer, len + 1 ); 656 | 657 | index += len + 1; 658 | 659 | return buf; 660 | } 661 | -------------------------------------------------------------------------------- /src/steam.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "steam/steam_api.h" 24 | #include "steam/isteamuserstats.h" 25 | #include "steam/isteamremotestorage.h" 26 | #include "steam/isteammatchmaking.h" 27 | #include "steam/isteamgameserver.h" 28 | #include "steam/steam_gameserver.h" 29 | 30 | #define STEAM_COD1_APPID 2620 31 | #define STEAM_APPID STEAM_COD1_APPID 32 | 33 | //#define USE_GS_AUTH_API 34 | 35 | extern "C" { 36 | void Q_strncpyz( char *dest, const char *src, int destsize ); 37 | void Com_sprintf( char *dest, int size, const char *fmt, ... ); 38 | char* Cvar_VariableString(const char*); 39 | 40 | #include "server.h" 41 | 42 | } 43 | 44 | class CoDSteamServer { 45 | public: 46 | bool initialized; 47 | 48 | CoDSteamServer( uint32 unIP, uint16 usSteamPort, uint16 usGamePort, uint16 usQueryPort, const char *pchVersionString) 49 | : 50 | m_CallbackSteamServersConnected( this, &CoDSteamServer::OnSteamServersConnected ), 51 | m_CallbackSteamServersConnectFailure( this, &CoDSteamServer::OnSteamServersConnectFailure ), 52 | m_CallbackSteamServersDisconnected( this, &CoDSteamServer::OnSteamServersDisconnected ) 53 | #if 0 54 | m_CallbackGSAuthTicketResponse( this, &SteamGameServerBridge::OnValidateAuthTicketResponse ), 55 | m_CallbackPolicyResponse( this, &SteamGameServerBridge::OnPolicyResponse ) 56 | #endif 57 | { 58 | initialized = false; 59 | 60 | const char* pchGameDir = ""; 61 | m_bConnectedToSteam = false; 62 | 63 | 64 | bool use_shared_udp = true; 65 | 66 | if ( !SteamGameServer_Init( unIP, usSteamPort, usGamePort, use_shared_udp ? MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE : usQueryPort, eServerModeAuthentication, pchVersionString ) ) 67 | { 68 | 69 | printf("SteamGameServer_Init(...) failed!\n"); 70 | return; 71 | } 72 | 73 | if(!SteamGameServer()) { 74 | printf("SteamGameServer() is NULL\n"); 75 | return; 76 | } 77 | 78 | initialized = true; 79 | 80 | 81 | // Set the "game dir". 82 | // This is currently required for all games. However, soon we will be 83 | // using the AppID for most purposes, and this string will only be needed 84 | // for mods. it may not be changed after the server has logged on 85 | SteamGameServer()->SetModDir( pchGameDir ); 86 | 87 | // These fields are currently required, but will go away soon. 88 | // See their documentation for more info 89 | SteamGameServer()->SetProduct( "Call of Duty Extended" ); 90 | SteamGameServer()->SetGameDescription( "Call of Duty Extended" ); 91 | 92 | // Is this is a dedicated server? The default value is false. 93 | SteamGameServer()->SetDedicatedServer( true ); 94 | 95 | // We don't support specators in our game. 96 | // .... but if we did: 97 | //SteamGameServer()->SetSpectatorPort( ... ); 98 | //SteamGameServer()->SetSpectatorServerName( ... ); 99 | 100 | // Initiate Anonymous logon. 101 | // Coming soon: Logging into authenticated, persistent game server account 102 | SteamGameServer()->LogOnAnonymous(); 103 | 104 | // We want to actively update the master server with our presence so players can 105 | // find us via the steam matchmaking/server browser interfaces 106 | //#ifdef USE_GS_AUTH_API 107 | SteamGameServer()->EnableHeartbeats( true ); 108 | //#endif 109 | } 110 | 111 | 112 | ~CoDSteamServer() { 113 | if(SteamGameServer() == NULL) 114 | return; 115 | 116 | #ifdef USE_GS_AUTH_API 117 | SteamGameServer()->EnableHeartbeats(false); 118 | #endif 119 | SteamGameServer()->LogOff(); 120 | SteamGameServer_Shutdown(); 121 | printf("~CoDSteamServer() Deconstructed!!!!!!!!!!!\n"); 122 | } 123 | 124 | bool IsConnectedToSteam() { return m_bConnectedToSteam; } 125 | CSteamID GetSteamID(); 126 | 127 | void SendUpdatedServerDetailsToSteam(); 128 | 129 | private: 130 | // 131 | // Various callback functions that Steam will call to let us know about events related to our 132 | // connection to the Steam servers for authentication purposes. 133 | // 134 | 135 | 136 | // Tells us when we have successfully connected to Steam 137 | STEAM_GAMESERVER_CALLBACK( CoDSteamServer, OnSteamServersConnected, SteamServersConnected_t, m_CallbackSteamServersConnected ); 138 | 139 | // Tells us when there was a failure to connect to Steam 140 | STEAM_GAMESERVER_CALLBACK( CoDSteamServer, OnSteamServersConnectFailure, SteamServerConnectFailure_t, m_CallbackSteamServersConnectFailure ); 141 | 142 | // Tells us when we have been logged out of Steam 143 | STEAM_GAMESERVER_CALLBACK( CoDSteamServer, OnSteamServersDisconnected, SteamServersDisconnected_t, m_CallbackSteamServersDisconnected ); 144 | 145 | 146 | // Track whether our server is connected to Steam ok (meaning we can restrict who plays based on 147 | // ownership and VAC bans, etc...) 148 | bool m_bConnectedToSteam; 149 | }; 150 | 151 | 152 | void CoDSteamServer::OnSteamServersConnected( SteamServersConnected_t *pLogonSuccess ) 153 | { 154 | printf("CoDSteamServer::OnSteamServersConnected(...)\n"); 155 | m_bConnectedToSteam = true; 156 | 157 | // log on is not finished until OnPolicyResponse() is called 158 | 159 | // Tell Steam about our server details 160 | SendUpdatedServerDetailsToSteam(); 161 | } 162 | 163 | 164 | void CoDSteamServer::OnSteamServersConnectFailure( SteamServerConnectFailure_t *pConnectFailure ) 165 | { 166 | printf("CoDSteamServer::OnSteamServersConnectFailure(...)\n"); 167 | m_bConnectedToSteam = false; 168 | } 169 | 170 | void CoDSteamServer::OnSteamServersDisconnected( SteamServersDisconnected_t *pLoggedOff ) 171 | { 172 | printf("CoDSteamServer::OnSteamServersDisconnected(...)\n"); 173 | m_bConnectedToSteam = false; 174 | } 175 | 176 | void CoDSteamServer::SendUpdatedServerDetailsToSteam() 177 | { 178 | 179 | // Tell the Steam authentication servers about our game 180 | char rgchServerName[128]; 181 | strcpy( rgchServerName, Cvar_VariableString("sv_hostname") ); 182 | 183 | // 184 | // Set state variables, relevant to any master server updates or client pings 185 | // 186 | 187 | // These server state variables may be changed at any time. Note that there is no lnoger a mechanism 188 | // to send the player count. The player count is maintained by steam and you should use the player 189 | // creation/authentication functions to maintain your player count. 190 | SteamGameServer()->SetMaxPlayerCount( atoi(Cvar_VariableString("sv_maxclients")) ); 191 | SteamGameServer()->SetPasswordProtected( false ); 192 | SteamGameServer()->SetServerName( rgchServerName ); 193 | SteamGameServer()->SetBotPlayerCount( 0 ); // optional, defaults to zero 194 | SteamGameServer()->SetMapName( Cvar_VariableString("mapname") ); 195 | 196 | #ifdef USE_GS_AUTH_API22 197 | 198 | // Update all the players names/scores 199 | for( uint32 i=0; i < MAX_PLAYERS_PER_SERVER; ++i ) 200 | { 201 | if ( m_rgClientData[i].m_bActive && m_rgpShips[i] ) 202 | { 203 | SteamGameServer()->BUpdateUserData( m_rgClientData[i].m_SteamIDUser, m_rgpShips[i]->GetPlayerName(), m_rguPlayerScores[i] ); 204 | } 205 | } 206 | #endif 207 | 208 | // game type is a special string you can use for your game to differentiate different game play types occurring on the same maps 209 | // When users search for this parameter they do a sub-string search of this string 210 | // (i.e if you report "abc" and a client requests "ab" they return your server) 211 | //SteamGameServer()->SetGameType( "dm" ); 212 | 213 | // update any rule values we publish 214 | //SteamMasterServerUpdater()->SetKeyValue( "rule1_setting", "value" ); 215 | //SteamMasterServerUpdater()->SetKeyValue( "rule2_setting", "value2" ); 216 | } 217 | 218 | 219 | extern "C" { 220 | 221 | int CSteamClient_Init() { 222 | 223 | if(!SteamAPI_Init()) 224 | return 0; 225 | if(!SteamFriends() || !SteamClient()) 226 | return 0; 227 | 228 | return 1; 229 | } 230 | 231 | static CoDSteamServer *codsteamserver = NULL; 232 | 233 | int CSteamServer_HandleIncomingPacket(const void* pData, int cbData, unsigned int srcIP, unsigned short srcPort) { 234 | if(codsteamserver == NULL) 235 | return 0; 236 | 237 | if(SteamGameServer()->HandleIncomingPacket(pData, cbData, srcIP, srcPort)) 238 | return 1; 239 | return 0; 240 | } 241 | 242 | int CSteamServer_Init(uint32_t ip, uint16_t steamPort, uint16_t gamePort, 243 | uint16_t queryPort, const char *versionString) { 244 | if(codsteamserver != NULL) { 245 | printf("Already server started!!!! STEAM\n"); 246 | return 0; 247 | } 248 | 249 | codsteamserver = new CoDSteamServer(ip, steamPort, gamePort, queryPort, versionString); 250 | 251 | if(codsteamserver == NULL) 252 | return 0; 253 | 254 | if(!codsteamserver->initialized) { 255 | 256 | delete codsteamserver; 257 | codsteamserver = NULL; 258 | return 0; 259 | } 260 | 261 | return 1; 262 | 263 | } 264 | 265 | void CSteamServer_Shutdown() { 266 | if(codsteamserver == NULL) 267 | return; 268 | delete codsteamserver; 269 | codsteamserver = NULL; 270 | } 271 | 272 | void CSteamServer_RunFrame() { 273 | if(codsteamserver == NULL) 274 | return; 275 | uint32 ip; 276 | uint16 port; 277 | char packet[32000] = {0}; 278 | int result; 279 | while( (result = SteamGameServer()->GetNextOutgoingPacket((void*)&packet,sizeof(packet),&ip,&port)) > 0) { 280 | //printf("ip = %lu, port = %u, packet = %s\n", ip, port, packet); 281 | netadr_t to; 282 | to.type = NA_IP; 283 | to._ip = ip; 284 | to.port = port; 285 | NET_SendPacket(NS_SERVER, result, packet, to); 286 | memset(packet,0,sizeof(packet)); 287 | } 288 | 289 | SteamGameServer_RunCallbacks(); 290 | 291 | codsteamserver->SendUpdatedServerDetailsToSteam(); 292 | } 293 | 294 | char *CSteamClient_GetPersonaName(char *s, int l) { 295 | Q_strncpyz(s, SteamFriends()->GetPersonaName(), l); 296 | } 297 | 298 | void CSteamClient_Shutdown() { 299 | SteamAPI_Shutdown(); 300 | } 301 | 302 | } -------------------------------------------------------------------------------- /src/steamwrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #ifdef STEAM_SUPPORT 19 | 20 | int CSteamClient_Init(); 21 | void CSteamClient_Shutdown(); 22 | char *CSteamClient_GetPersonaName(); 23 | 24 | //Server Functions 25 | void CSteamServer_Shutdown(); 26 | int CSteamServer_Init(uint32_t ip, uint16_t steamPort, uint16_t gamePort, 27 | uint16_t queryPort, const char *versionString); 28 | void CSteamServer_RunFrame(); 29 | 30 | #endif -------------------------------------------------------------------------------- /src/stripdebuginfo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | scriptdir=`dirname ${0}` 4 | scriptdir=`(cd ${scriptdir}; pwd)` 5 | scriptname=`basename ${0}` 6 | 7 | set -e 8 | 9 | function errorexit() 10 | { 11 | errorcode=${1} 12 | shift 13 | echo $@ 14 | exit ${errorcode} 15 | } 16 | 17 | function usage() 18 | { 19 | echo "USAGE ${scriptname} " 20 | } 21 | 22 | tostripdir=`dirname "$1"` 23 | tostripfile=`basename "$1"` 24 | 25 | 26 | if [ -z ${tostripfile} ] ; then 27 | usage 28 | errorexit 0 "tostrip must be specified" 29 | fi 30 | 31 | cd "${tostripdir}" 32 | 33 | debugdir=.debug 34 | debugfile="${tostripfile}.debug" 35 | 36 | if [ ! -d "${debugdir}" ] ; then 37 | echo "creating dir ${tostripdir}/${debugdir}" 38 | mkdir -p "${debugdir}" 39 | fi 40 | echo "stripping ${tostripfile}, putting debug info into ${debugfile}" 41 | objcopy --only-keep-debug "${tostripfile}" "${debugdir}/${debugfile}" 42 | strip --strip-debug --strip-unneeded "${tostripfile}" 43 | objcopy --add-gnu-debuglink="${debugdir}/${debugfile}" "${tostripfile}" 44 | chmod -x "${debugdir}/${debugfile}" 45 | -------------------------------------------------------------------------------- /src/surfaceflags.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #define CONTENTS_SOLID 0x00000001 19 | #define CONTENTS_WATER 0x00000020 20 | #define CONTENTS_BODY 0x02000000 // should never be on a brush, only in game 21 | #define CONTENTS_CORPSE 0x04000000 22 | 23 | #define CONTENTS_TRIGGER 0x40000000 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/sv_game.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "bg_public.h" 19 | #include "server.h" 20 | #include "script.h" 21 | 22 | SV_SendServerCommand_t SV_SendServerCommand = (SV_SendServerCommand_t)0x808B900; 23 | SV_GentityNum_t SV_GentityNum = (SV_GentityNum_t)0x8089258; 24 | 25 | T_SetBrushModel_t T_SetBrushModel; 26 | T_UnlinkEntity_t T_UnlinkEntity; 27 | T_LinkEntity_t T_LinkEntity; 28 | BG_EvaluateTrajectory_t BG_EvaluateTrajectory; 29 | BG_EvaluateTrajectoryDelta_t BG_EvaluateTrajectoryDelta; 30 | 31 | void set_trap_func_ptr( void ) { 32 | T_SetBrushModel = (T_SetBrushModel_t)GAME("trap_SetBrushModel"); 33 | T_LinkEntity = (T_LinkEntity_t)GAME("trap_LinkEntity"); 34 | T_UnlinkEntity = (T_UnlinkEntity_t)GAME("trap_UnlinkEntity"); 35 | G_Spawn = (G_Spawn_t)GAME("G_Spawn"); 36 | G_SetOrigin = (G_SetOrigin_t)GAME("G_SetOrigin"); 37 | G_SetAngle = (G_SetAngle_t)GAME("G_SetAngle"); 38 | BG_EvaluateTrajectory = (BG_EvaluateTrajectory_t)GAME("BG_EvaluateTrajectory"); 39 | BG_EvaluateTrajectoryDelta = (BG_EvaluateTrajectoryDelta_t)GAME("BG_EvaluateTrajectoryDelta"); 40 | 41 | G_FreeEntity = (G_FreeEntity_t)GAME("G_FreeEntity"); 42 | 43 | void _Scr_FreeEntity(gentity_t*); 44 | __jmp(GAME("Scr_FreeEntity"), (unsigned)_Scr_FreeEntity); 45 | void _SpectatorClientEndFrame(gentity_t*); 46 | //__jmp(GAME("SpectatorClientEndFrame"), _SpectatorClientEndFrame); 47 | __call(GAME("ClientEndFrame")+0x98, (unsigned)_SpectatorClientEndFrame); 48 | 49 | #if 0 50 | scr_entityfield_t *fields = (scr_entityfield_t*)( GAME("vmMain") + 0x28094 ); 51 | FILE *fp = fopen("entfields.txt", "w"); 52 | 53 | fprintf(fp, "scr_entityfield_t scr_entityfields[] = {\n"); 54 | for(int i = 0; fields[i].name; i++) { 55 | fprintf(fp, "{\"%s\", %u, %u, %x},\n", fields[i].name, fields[i].offset, fields[i].type, fields[i].set); 56 | } 57 | fprintf(fp, "};\n"); 58 | fclose(fp); 59 | #endif 60 | } -------------------------------------------------------------------------------- /src/sv_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "server.h" 19 | #include 20 | 21 | SV_SetConfigstring_t SV_SetConfigstring = (SV_SetConfigstring_t)0x8089BF0; 22 | SV_GetConfigstring_t SV_GetConfigstring = (SV_GetConfigstring_t)0x808B05C; 23 | 24 | netadr_t authorizeAddress; 25 | netadr_t masterAddress; 26 | 27 | LinkedList banlist = NULL; 28 | 29 | void X_ReadBannedList(bool print_t) { 30 | FILE *f; 31 | netadr_t adr; 32 | banInfo_t *ban; 33 | char buf[256]; 34 | char* bufp = NULL; 35 | 36 | list_clear(&banlist); 37 | 38 | f = fopen("ipbans.txt", "r"); 39 | if(f) { 40 | while(fgets(buf, sizeof(buf), f)) { 41 | char *reason = strchr(buf, ':'); 42 | if(reason != NULL) 43 | *reason++ = '\0'; 44 | bufp = utrim(buf); 45 | if(!strlen(bufp)) 46 | continue; 47 | NET_StringToAdr(bufp, &adr); 48 | ban = (banInfo_t*)xalloc(sizeof(banInfo_t)); 49 | *ban->reason = 0; 50 | ban->type = IPBAN; 51 | ban->adr = adr; 52 | if(reason != NULL) 53 | strncpy(ban->reason, reason, sizeof(ban->reason)); 54 | _list_add(&banlist, ban); 55 | if(print_t) 56 | printf("Added IP '%s' to the list.\n", NET_BaseAdrToString(adr)); 57 | } 58 | fclose(f); 59 | } 60 | 61 | f = fopen("muidbans.txt", "r"); 62 | 63 | if(f) { 64 | while(fgets(buf, sizeof(buf), f)) { 65 | bufp = utrim(buf); 66 | if(!strlen(bufp)) 67 | continue; 68 | if(atoi(bufp) == 0) 69 | continue; 70 | ban = (banInfo_t*)xalloc(sizeof(banInfo_t)); 71 | *ban->reason = 0; 72 | ban->type = MUIDBAN; 73 | Q_strncpyz(ban->mUID, bufp, sizeof(ban->mUID)); 74 | _list_add(&banlist, ban); 75 | if(print_t) 76 | cprintf(PRINT_INFO, "Added mUID '%s' to the list.\n", bufp); 77 | } 78 | fclose(f); 79 | } 80 | } 81 | 82 | cvar_t *developer; 83 | 84 | void SV_Init( void ) { 85 | void (*init)( void ); 86 | #if CODPATCH == 1 87 | *(int*)&init = 0x808A94C; 88 | #else if CODPATCH == 5 89 | *(int*)&init = 0x80913B3; 90 | #endif 91 | 92 | init(); 93 | 94 | if(clientsize != sizeof(client_t)) { 95 | 96 | cprintf(PRINT_UNDERLINE | PRINT_ERR, "ERROR: client_t size doesn't fit clientsize!!! %i != %i\n", sizeof(client_t), clientsize); 97 | } else { 98 | 99 | //cprintf(PRINT_UNDERLINE | PRINT_GOOD, "GOOD: SIZE IS SAME OF CLIENT\n"); 100 | } 101 | 102 | if ( NET_StringToAdr( x_mastername, &x_master ) ) 103 | x_master.port = BigShort( 20510 ); 104 | 105 | X_ReadBannedList(true); 106 | 107 | developer = Cvar_Get("developer", "0", 256); 108 | sv_running = Cvar_Get("sv_running", "0", 64); 109 | sv_maxclients = Cvar_Get("sv_maxclients", "20", 36); 110 | sv_privateClients = Cvar_Get("sv_privateClients", "0", 4); 111 | g_gametype = Cvar_Get("g_gametype", "dm", 36); 112 | mapname = Cvar_Get("mapname", "nomap", 68); 113 | sv_hostname = Cvar_Get("sv_hostname", "CoDExtendedHost", 5); 114 | sv_maxRate = Cvar_Get("sv_maxRate", "0", 5); 115 | sv_maxPing = Cvar_Get("sv_maxPing", "0", 5); 116 | sv_minPing = Cvar_Get("sv_minPing", "0", 5); 117 | sv_floodProtect = Cvar_Get("sv_floodProtect", "1", 5); 118 | sv_allowAnonymous = Cvar_Get("sv_allowAnonymous", "", 4); 119 | sv_showCommands = Cvar_Get("sv_showCommands", "0", 0); 120 | sv_pure = Cvar_Get("sv_pure", "0", 12); 121 | sv_serverid = Cvar_Get("sv_serverid", "0", 72); 122 | rconPassword = Cvar_Get("rconPassword", "", 256); 123 | sv_privatePassword = Cvar_Get("sv_privatePassword", "", 256); 124 | sv_fps = Cvar_Get("sv_fps", "20", 256); 125 | sv_timeout = Cvar_Get("sv_timeout", "240", 256); 126 | sv_zombietime = Cvar_Get("sv_zombietime", "2", 256); 127 | sv_allowDownload = Cvar_Get("sv_allowDownload", "1", 1); 128 | Cvar_Get("sv_wwwDownload", "1", 1); 129 | Cvar_Get("sv_wwwBaseURL", "", CVAR_SYSTEMINFO | 1); 130 | /*sv_master1 = Cvar_Get("sv_master1", "codmaster.activision.com", 0); 131 | sv_master2 = Cvar_Get("sv_master2", "", 1); 132 | sv_master3 = Cvar_Get("sv_master3", "", 1); 133 | sv_master4 = Cvar_Get("sv_master4", "", 1); 134 | sv_master5 = Cvar_Get("sv_master5", "", 1);*/ 135 | sv_reconnectlimit = Cvar_Get("sv_reconnectlimit", "3", 0); 136 | sv_showloss = Cvar_Get("sv_showloss", "0", 0); 137 | sv_padPackets = Cvar_Get("sv_padPackets", "0", 0); 138 | sv_killserver = Cvar_Get("sv_killserver", "0", 0); 139 | sv_onlyVisibleClients = Cvar_Get("sv_onlyVisibleClients", "0", 0); 140 | sv_showAverageBPS = Cvar_Get("sv_showAverageBPS", "0", 0); 141 | sv_mapRotation = Cvar_Get("sv_mapRotation", "", 0); 142 | sv_mapRotationCurrent = Cvar_Get("sv_mapRotationCurrent", "", 0); 143 | protocol = Cvar_Get("protocol", "1", 68); 144 | shortversion = Cvar_Get("shortversion", "1.1", 68); 145 | dedicated = Cvar_Get("dedicated", "2", 64); 146 | 147 | x_globalbans = Cvar_Get("x_globalbans", "1", 0); 148 | x_spectator_noclip = Cvar_Get("x_spectator_noclip", "0", CVAR_ARCHIVE); 149 | x_connectmessage = Cvar_Get("x_connectmessage", "", CVAR_ARCHIVE); 150 | cl_allowDownload = Cvar_Get("cl_allowDownload", "0", CVAR_SYSTEMINFO); 151 | 152 | Cvar_Get("rate", "25000", CVAR_SYSTEMINFO); 153 | Cvar_Get("snaps", "40", CVAR_SYSTEMINFO); 154 | 155 | extern cvar_t *x_cl_adsair; 156 | x_cl_adsair = Cvar_Get("x_cl_adsair", "1", 0); 157 | 158 | cvar_t *x_nopbots = Cvar_Get("x_nopbots", "0", 0); 159 | /* 160 | NOP SV_BotUsermove calls 161 | */ 162 | 163 | if(x_nopbots->integer) { 164 | __nop(0x808D152, 5); 165 | __nop(0x808D492, 5); 166 | } 167 | 168 | #if CODPATCH == 5 169 | sv_disableClientConsole = Cvar_Get("sv_disableClientConsole", "0", 8); 170 | #endif 171 | 172 | x_authorize = Cvar_Get("x_authorize", "0", 0); 173 | /*Both needed for deathrun server to prevent players from blocking each other*/ 174 | x_contents = Cvar_Get("x_contents", "-1", 0); 175 | x_stuck = Cvar_Get("x_stuck", "0", 0); 176 | 177 | Cvar_Get("codextended", va("CoDExtended v%d", CURRENTBUILD), CVAR_SERVERINFO | CVAR_ROM | CVAR_NORESTART); 178 | //Cvar_Get("codextended", "This server is powered by CoDExtended.", CVAR_SERVERINFO | CVAR_ROM | CVAR_NORESTART); 179 | 180 | x_bannedmessage = Cvar_Get("x_bannedmsg", "You have been banned from this server.", 0); 181 | 182 | sv_master[0] = Cvar_Get("sv_master1", "codmaster.activision.com", 0); 183 | sv_master[1] = Cvar_Get("sv_master2", "", CVAR_ARCHIVE); 184 | sv_master[2] = Cvar_Get("sv_master3", "", CVAR_ARCHIVE); 185 | sv_master[3] = Cvar_Get("sv_master4", "", CVAR_ARCHIVE); 186 | sv_master[4] = Cvar_Get("sv_master5", "", CVAR_ARCHIVE); 187 | 188 | #define MASTER_SERVER_NAME "codmaster.activision.com" 189 | 190 | cprintf(PRINT_GOOD, "Resolving %s\n", MASTER_SERVER_NAME ); 191 | if ( NET_StringToAdr( MASTER_SERVER_NAME, &masterAddress ) ) 192 | masterAddress.port = BigShort( 20510 ); 193 | 194 | #define AUTHORIZE_SERVER_NAME "codauthorize.activision.com" 195 | 196 | if ( !authorizeAddress.ip[0] && authorizeAddress.type != NA_BAD ) { 197 | cprintf(PRINT_GOOD, "Resolving %s\n", AUTHORIZE_SERVER_NAME ); 198 | if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &authorizeAddress ) ) { 199 | cprintf(PRINT_ERR, "Couldn't resolve address\n" ); 200 | return; 201 | } 202 | authorizeAddress.port = BigShort( 20500 ); 203 | cprintf(PRINT_GOOD, "%s resolved to %i.%i.%i.%i:%i\n", AUTHORIZE_SERVER_NAME, 204 | authorizeAddress.ip[0], authorizeAddress.ip[1], 205 | authorizeAddress.ip[2], authorizeAddress.ip[3], 206 | BigShort( authorizeAddress.port ) ); 207 | } 208 | } 209 | 210 | void SV_Shutdown(char *finalmsg) { 211 | void (*o)(char*) = (void(*)(char*))0x808AD8C; 212 | o(finalmsg); 213 | } 214 | 215 | void SV_SpawnServer(char *server) { 216 | void (*spawnserver)(char*) = (void(*)(char*))0x808A220; 217 | spawnserver(server); 218 | } -------------------------------------------------------------------------------- /src/sv_snapshot.asm: -------------------------------------------------------------------------------- 1 | ; This file is part of CoDExtended. 2 | ; 3 | ; CoDExtended is free software: you can redistribute it and/or modify 4 | ; it under the terms of the GNU General Public License as published by 5 | ; the Free Software Foundation, either version 3 of the License, or 6 | ; (at your option) any later version. 7 | ; 8 | ; CoDExtended is distributed in the hope that it will be useful, 9 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ; GNU General Public License for more details. 12 | ; 13 | ; You should have received a copy of the GNU General Public License 14 | ; along with CoDExtended. If not, see . 15 | 16 | SECTION .text 17 | 18 | extern SV_AddEntitiesVisibleFromPoint_Stub 19 | 20 | global SV_AddEntitiesVisibleFromPoint_Intercept 21 | SV_AddEntitiesVisibleFromPoint_Intercept: 22 | ; eax = ent 23 | mov esi, [ebp + 0Ch] ; clientNum 24 | push esi 25 | mov esi, eax 26 | push eax 27 | call SV_AddEntitiesVisibleFromPoint_Stub 28 | test eax, eax 29 | mov eax, esi 30 | jz loc_808E336 31 | 32 | loc_808E48C: ; not visible 33 | mov esi, 808E48Ch 34 | jmp esi 35 | 36 | loc_808E336: ; visible 37 | mov esi, 808E336h 38 | jmp esi 39 | 40 | global TestGetAddr 41 | TestGetAddr: 42 | mov eax, SV_AddEntitiesVisibleFromPoint_Intercept 43 | retn -------------------------------------------------------------------------------- /src/sv_snapshot.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "server.h" 19 | 20 | int SV_AddEntitiesVisibleFromPoint_Stub(sharedEntity_t *ent, unsigned clientNum) { 21 | //printf("ent = %x, clientNum = %x\n", ent, clientNum); 22 | if(clientNum > 1023) 23 | return 1; 24 | 25 | if(ent == NULL) 26 | return 1; 27 | 28 | //printf("ent number = %u, svFlags = %u, singleClient = %u\n", ent->s.number, ent->r.svFlags, ent->r.singleClient); 29 | if(ent->r.svFlags & SVF_SINGLECLIENT) { 30 | //printf("singleclient ent, clientNum = %u, r.singleClient = %u\n", clientNum, ent->r.singleClient); 31 | if(clientNum == ent->r.singleClient) { 32 | return 0; 33 | } else 34 | return 1; 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /src/sv_world.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "server.h" 19 | 20 | SV_Trace_t SV_Trace = (SV_Trace_t)0x80916F4; 21 | -------------------------------------------------------------------------------- /src/unix_net.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "server.h" 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include // bk001204 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | void SV_NocPacket(netadr_t,msg_t*); 34 | 35 | void SockadrToNetadr( struct sockaddr_in *s, netadr_t *a ) { 36 | *(int *)&a->ip = *(int *)&s->sin_addr; 37 | a->port = s->sin_port; 38 | a->type = NA_IP; 39 | } 40 | 41 | qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) { 42 | int ret; 43 | struct sockaddr_in from; 44 | int fromlen; 45 | int net_socket; 46 | int protocol; 47 | int err; 48 | 49 | for ( protocol = 0 ; protocol < 2 ; protocol++ ) 50 | { 51 | /* 52 | if ( protocol == 0 ) { 53 | //net_socket = ip_socket; 54 | } else { 55 | //net_socket = ipx_socket; 56 | 57 | } 58 | */ 59 | net_socket = (protocol == 0) ? *(int*)0x80E688C : *(int*)0x83C8700; 60 | 61 | if ( !net_socket ) { 62 | continue; 63 | } 64 | 65 | fromlen = sizeof( from ); 66 | ret = recvfrom( net_socket, net_message->data, net_message->maxsize 67 | , 0, (struct sockaddr *)&from, &fromlen ); 68 | 69 | SockadrToNetadr( &from, net_from ); 70 | // bk000305: was missing 71 | net_message->readcount = 0; 72 | 73 | if ( ret == -1 ) { 74 | err = errno; 75 | 76 | if ( err == EWOULDBLOCK || err == ECONNREFUSED ) { 77 | continue; 78 | } 79 | //Com_Printf( "NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString( *net_from ) ); 80 | continue; 81 | } 82 | 83 | if ( ret == net_message->maxsize ) { 84 | Com_Printf( "Oversize packet from %s\n", NET_AdrToString( *net_from ) ); 85 | continue; 86 | } 87 | 88 | net_message->cursize = ret; 89 | SV_NocPacket(*net_from, net_message); 90 | return qtrue; 91 | } 92 | 93 | return qfalse; 94 | } -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | // You must free the result if result is non-NULL. 22 | char *str_replace(char *orig, char *rep, char *with) { 23 | char *result; // the return string 24 | char *ins; // the next insert point 25 | char *tmp; // varies 26 | int len_rep; // length of rep 27 | int len_with; // length of with 28 | int len_front; // distance between rep and end of last rep 29 | int count; // number of replacements 30 | 31 | if (!orig) 32 | return NULL; 33 | if (!rep || !(len_rep = strlen(rep))) 34 | return NULL; 35 | if (!(ins = strstr(orig, rep))) 36 | return NULL; 37 | if (!with) 38 | with = ""; 39 | len_with = strlen(with); 40 | 41 | for (count = 0; tmp = strstr(ins, rep); ++count) { 42 | ins = tmp + len_rep; 43 | } 44 | 45 | // first time through the loop, all the variable are set correctly 46 | // from here on, 47 | // tmp points to the end of the result string 48 | // ins points to the next occurrence of rep in orig 49 | // orig points to the remainder of orig after "end of rep" 50 | tmp = result = (char*)malloc(strlen(orig) + (len_with - len_rep) * count + 1); 51 | 52 | if (!result) 53 | return NULL; 54 | 55 | while (count--) { 56 | ins = strstr(orig, rep); 57 | len_front = ins - orig; 58 | tmp = strncpy(tmp, orig, len_front) + len_front; 59 | tmp = strcpy(tmp, with) + len_with; 60 | orig += len_front + len_rep; // move to next "end of rep" 61 | } 62 | strcpy(tmp, orig); 63 | return result; 64 | } 65 | 66 | int file_exists(const char* file) { 67 | struct stat st; 68 | if (stat(file, &st) >= 0) 69 | return 1; 70 | return 0; 71 | } 72 | 73 | size_t filesize(const char* file) { 74 | struct stat st; 75 | if (stat(file, &st) >= 0) 76 | return st.st_size; 77 | return 0; 78 | } 79 | 80 | int startsWith(const char *str, const char *pre) { 81 | size_t lenpre = strlen(pre), lenstr = strlen(str); 82 | return lenstr < lenpre ? 0 : strncmp(pre, str, lenpre) == 0; 83 | } -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #ifndef X_UTIL_H 19 | #define X_UTIL_H 20 | 21 | #include 22 | #include 23 | #include "openssl/md5.h" 24 | 25 | typedef unsigned char byte; 26 | 27 | static int search_memory(int current, int end, byte* bytes, size_t len) { 28 | while((memcmp((void*)current, bytes, len)) && (current < end)) 29 | current++; 30 | return (current == end) ? -1 : current; 31 | } 32 | 33 | static int patch_memory(int start, int end, byte* search_for, byte* patched, size_t len) { 34 | int s = search_memory(start, end, search_for, len); 35 | if(-1 != s) 36 | memcpy((void*)s, patched, len); 37 | return s; 38 | } 39 | 40 | struct list_element_t { 41 | void *data; 42 | struct list_element_t *next; 43 | }; 44 | 45 | typedef struct list_element_t *LinkedList; 46 | 47 | #define new(x, y) (x*)malloc(sizeof(x) * y) 48 | #define list_empty(list) (list == NULL) 49 | #define list_each_element(it, list) \ 50 | struct list_element_t *it = list; \ 51 | for(;it!=NULL;it=it->next) 52 | #define list_each(type, it, list) \ 53 | struct list_element_t *LIST_CURRENT_ELEMENT = list; type it = (list) ? list->data : NULL; \ 54 | for(;LIST_CURRENT_ELEMENT!=NULL;it=(type)LIST_CURRENT_ELEMENT->data,LIST_CURRENT_ELEMENT=LIST_CURRENT_ELEMENT->next) 55 | #define list_remove(list, e) do { \ 56 | struct list_element_t *LIST_TEMP_ELEMENT = list; \ 57 | if(e == list) { \ 58 | list = list->next; free(e->data); free(e); \ 59 | } else { \ 60 | while(LIST_TEMP_ELEMENT->next != e) LIST_TEMP_ELEMENT = LIST_TEMP_ELEMENT->next; \ 61 | LIST_TEMP_ELEMENT->next = e->next; free(e->data); free(e); \ 62 | } \ 63 | } while(0) 64 | 65 | typedef void (*Com_Error_t)(int code, const char *fmt, ...); 66 | extern Com_Error_t Com_Error; 67 | 68 | static void list_clear(LinkedList *list) { 69 | if(*list == NULL) 70 | return; 71 | 72 | LinkedList tmp = *list; 73 | 74 | while(*list) { 75 | tmp = *list; 76 | *list = (*list)->next; 77 | free(tmp->data); 78 | free(tmp); 79 | } 80 | *list = NULL; 81 | } 82 | 83 | static LinkedList _list_add(LinkedList *list, void *data) { 84 | LinkedList n = NULL, cur = *list; 85 | n = (LinkedList)malloc(sizeof(*n)); 86 | if(n == NULL) { 87 | Com_Error(0, "Out of memory!"); 88 | return NULL; 89 | } 90 | n->next = NULL; 91 | n->data = data; 92 | if(!cur) 93 | *list = n; 94 | else { 95 | while(cur->next) 96 | cur = cur->next; 97 | cur->next = n; 98 | } 99 | return n; 100 | } 101 | 102 | // You must free the result if result is non-NULL. 103 | char *str_replace(char *orig, char *rep, char *with); 104 | size_t filesize(const char* file); 105 | int startsWith(const char *str, const char *pre); 106 | 107 | /* 108 | Hooking 109 | */ 110 | 111 | static void __nop(unsigned int start, unsigned int end) { 112 | int len = ( end < start ) ? end : ( end - start ), i; 113 | mprotect((void *)start, len, PROT_READ | PROT_WRITE | PROT_EXEC); 114 | memset((void*)start, 0x90, len); 115 | } 116 | 117 | static void __jmp(unsigned int off, unsigned int loc) { 118 | mprotect((void*)off, 5, PROT_READ | PROT_WRITE | PROT_EXEC); 119 | *(unsigned char*)off = 0xe9; 120 | int foffset = loc - (off + 5); 121 | memcpy((void*)(off + 1), &foffset, 4); 122 | } 123 | 124 | static void __call(unsigned int off, unsigned int loc) { 125 | mprotect((void *)off, 5, PROT_READ | PROT_WRITE | PROT_EXEC); 126 | int foffset = loc - (off + 5); 127 | memcpy((void *)(off + 1), &foffset, 4); 128 | } 129 | 130 | /* 131 | MD5 132 | */ 133 | 134 | static char xhash_md5[33]; 135 | 136 | static char* get_md5(char* str) { 137 | unsigned char digest[MD5_DIGEST_LENGTH]; 138 | MD5((unsigned char*)str, strlen(str), (unsigned char*)&digest); 139 | for(int i = 0; i < 16; i++) 140 | sprintf(&xhash_md5[i*2], "%02x", (unsigned int)digest[i]); 141 | return &xhash_md5[0]; 142 | } 143 | 144 | static char *get_md5b(unsigned char *buf, size_t len) { 145 | unsigned char digest[MD5_DIGEST_LENGTH]; 146 | MD5(buf, len, (unsigned char*)&digest); 147 | for(int i = 0; i < 16; i++) 148 | sprintf(&xhash_md5[i*2], "%02x", (unsigned int)digest[i]); 149 | return &xhash_md5[0]; 150 | } 151 | 152 | static char* get_pass_hash(char* password, char* salt) { 153 | char tmp[32*((!strcmp(salt,""))?1:2)+1]; 154 | if(strcmp(salt,"")) { 155 | sprintf(tmp, "%s", get_md5(salt)); 156 | sprintf(tmp, "%s%s", tmp, get_md5(password)); 157 | } else { 158 | sprintf(tmp, "%s", get_md5(password)); 159 | } 160 | return get_md5(tmp); 161 | } 162 | 163 | 164 | static void dumpbase(int* base, size_t len, const char *fn) { 165 | static char dumpbase_path[64]; 166 | 167 | snprintf(dumpbase_path, 63, "./dumps/%s.dump", fn); 168 | 169 | unsigned int result; 170 | float rf; 171 | char* rstr; 172 | 173 | FILE* f = fopen(dumpbase_path, "wb"); 174 | if(f) { 175 | fprintf(f, "File: %s\nDUMPFILE\n\n"); 176 | 177 | for(unsigned int i = 0; i < len; i++) { 178 | result = *(unsigned int*)(base + i); 179 | rf = *(float*)(base + i); 180 | rstr = (char*)(base + i); 181 | fprintf(f, "%d: Hex: %x, Decimal: %d, Float: %f, String: %s\n", i, result, result, rf, rstr); 182 | } 183 | fclose(f); 184 | } 185 | 186 | printf("Successfully dumped '%s' to location '%s'.\n", fn, dumpbase_path); 187 | } 188 | 189 | 190 | /* 191 | Thanks to kung foo man for providing unprotect_lib 192 | */ 193 | 194 | static int unprotect_lib(char *libname) 195 | { 196 | char buf[512]; 197 | char flags[4]; 198 | void *low, *high; 199 | FILE *fp; 200 | fp = fopen("/proc/self/maps", "r"); 201 | if ( ! fp) 202 | return 0; 203 | while (fgets(buf, sizeof(buf), fp)) 204 | { 205 | if ( ! strstr(buf, libname)) 206 | continue; 207 | if (sscanf (buf, "%p-%p %4c", &low, &high, flags) != 3) 208 | continue; 209 | //printf(buf); 210 | //printf("%08x %08x diff:%.8p\n", low, high, (int)high-(int)low); 211 | mprotect((void *)low, (int)high-(int)low, PROT_READ | PROT_WRITE | PROT_EXEC); 212 | } 213 | fclose(fp); 214 | return 1; 215 | } 216 | 217 | static inline void xor_crypt(char *key, char *string, int n) { 218 | int i; 219 | int c_use = 'x'; 220 | int keyLength = strlen(key); 221 | for(i = 0; i < n; i++) 222 | string += string[i] ^ (c_use /*+i*/) % 255;//string[i] = string[i] ^ key[i%keyLength]; 223 | } 224 | 225 | #endif -------------------------------------------------------------------------------- /src/webserver.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #ifndef F_WEBSERVER 19 | #include 20 | void WebServer_Stop() {} 21 | bool WebServer_Start() {} 22 | #else 23 | 24 | #include "server.h" 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include // bk001204 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | 41 | bool bServRunning = false; 42 | 43 | volatile int server_sock; 44 | pthread_t h_thread_serverListener; 45 | 46 | 47 | char *responseHeader = "HTTP/1.1 200 OK\r\n" 48 | "Content-Type: text/html; charset=UTF-8\r\n\r\n"; 49 | 50 | char response[] = "HTTP/1.1 200 OK\r\n" 51 | "Content-Type: text/html; charset=UTF-8\r\n\r\n" 52 | "Bye-bye baby bye-bye" 53 | "" 56 | "

Goodbye, world!

\r\n"; 57 | 58 | volatile char r_contents[40321]; 59 | 60 | void *WebServer_Listen(void *arg) { 61 | int client_fd; 62 | 63 | struct sockaddr_in client_addr; 64 | socklen_t sin_len = sizeof(client_addr); 65 | 66 | char string[1024] = {0}; 67 | int send_len, i; 68 | 69 | while(bServRunning) { 70 | client_fd = accept(server_sock, (struct sockaddr*)&client_addr, &sin_len); 71 | cprintf(PRINT_GOOD, "Got connection on webserver.\n"); 72 | 73 | if(client_fd == -1) { 74 | cprintf(PRINT_ERR | PRINT_UNDERLINE, "Error: Couldn't accept.\n"); 75 | goto exthr; 76 | } 77 | 78 | *r_contents = 0; 79 | Com_sprintf(r_contents, sizeof(r_contents), "%s", responseHeader); 80 | /* add the html header etc */ 81 | 82 | Q_strcat(r_contents, sizeof(r_contents), "Webserver info CoDExtended (v20)
Players on server
"); 83 | client_t *cl; 84 | 85 | for(i = 0; i < sv_maxclients->integer; i++) { 86 | cl = getclient(i); 87 | if(cl->state >= CS_CONNECTED) { 88 | 89 | string[0] = '\0'; 90 | 91 | Com_sprintf(string, sizeof(string), "%d: %s
", get_client_number(cl), cl->name); 92 | 93 | Q_strcat(r_contents, sizeof(r_contents), string); 94 | } 95 | } 96 | 97 | send_len = strlen(r_contents); 98 | 99 | write(client_fd, r_contents, send_len); 100 | close(client_fd); 101 | } 102 | exthr: 103 | bServRunning = false; 104 | return NULL; 105 | } 106 | 107 | bool WebServer_Start() { 108 | struct sockaddr_in serveraddr; 109 | 110 | server_sock = socket(AF_INET, SOCK_STREAM, 0); 111 | if(server_sock < 0) { 112 | cprintf(PRINT_ERR | PRINT_UNDERLINE, "Error: Can't open socket.\n"); 113 | return false; 114 | } 115 | 116 | int one = 1; 117 | 118 | setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)); 119 | 120 | int port = 28960; 121 | serveraddr.sin_family = AF_INET; 122 | serveraddr.sin_addr.s_addr = INADDR_ANY; 123 | serveraddr.sin_port = htons(port); 124 | 125 | if(bind(server_sock, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1) { 126 | cprintf(PRINT_UNDERLINE | PRINT_ERR, "Error: Failed to bind.\n"); 127 | return false; 128 | } 129 | 130 | listen(server_sock, 5); 131 | bServRunning = true; 132 | 133 | int err = pthread_create(&(h_thread_serverListener), NULL, &WebServer_Listen, NULL); 134 | 135 | if(err != 0) { 136 | cprintf(PRINT_ERR | PRINT_UNDERLINE, "Error: Could not create webserver listen thread.\n"); 137 | return false; 138 | } else 139 | cprintf(PRINT_GOOD, "Webserver listening thread created.\n"); 140 | } 141 | 142 | void WebServer_Stop() { 143 | bServRunning = false; 144 | } 145 | #endif -------------------------------------------------------------------------------- /src/x_clientcmds.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CoDExtended. 3 | 4 | CoDExtended is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | CoDExtended is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with CoDExtended. If not, see . 16 | */ 17 | 18 | #include "server.h" 19 | 20 | int call_cmd_callvote = 0; 21 | int call_onsameteam = 0; 22 | 23 | void Cmd_CallVote(unsigned gentity) { 24 | return; //dont call vote.. 25 | 26 | if(!call_cmd_callvote) 27 | call_cmd_callvote = GAME("Cmd_CallVote_f"); 28 | void (*callvote)(unsigned); 29 | *(int*)&callvote = call_cmd_callvote; 30 | 31 | char arg1[MAX_STRING_TOKENS]; 32 | char arg2[MAX_STRING_TOKENS]; 33 | 34 | Cmd_ArgvBuffer( 1, arg1, sizeof( arg1 ) ); 35 | Cmd_ArgvBuffer( 2, arg2, sizeof( arg2 ) ); 36 | 37 | if( strchr( arg1, ';' ) || strchr( arg2, ';' ) || !is_good_string(arg1) || !is_good_string(arg2)) { 38 | SV_SendServerCommand(*(int*)gentity, 0, "e \"GAME_INVALIDVOTESTRING\""); 39 | return; 40 | } 41 | 42 | callvote( gentity ); 43 | /*signed int (*Script_IsValidGametype)(char*); 44 | *(int*)&Script_IsValidGametype = GAME("Scr_IsValidGameType"); 45 | 46 | int i; 47 | char arg1[MAX_STRING_TOKENS]; 48 | char arg2[MAX_STRING_TOKENS]; 49 | cvar_t* g_gametype = Cvar_Get("g_gametype", "dm", 0); 50 | cvar_t* g_allowvote = Cvar_Get("g_allowvote", "0", 0); 51 | if(!g_allowvote->integer) { 52 | SV_SendServerCommand(cl, 0, "e \"GAME_VOTINGNOTENABLED\""); 53 | return; 54 | } 55 | 56 | if(*(int*)&level[2840]) { 57 | SV_SendServerCommand(cl, 0, "e \"GAME_VOTEALREADYINPROGRESS\""); 58 | return; 59 | } 60 | 61 | gentity_t* ent = cl->gentity; 62 | 63 | if(*(int*)(ent + 8572) == 3) { 64 | SV_SendServerCommand(cl, 0, print" \"GAME_NOSPECTATORCALLVOTE\""); 65 | return; 66 | } 67 | 68 | // make sure it is a valid command to vote on 69 | Cmd_ArgvBuffer( 1, arg1, sizeof( arg1 ) ); 70 | Cmd_ArgvBuffer( 2, arg2, sizeof( arg2 ) ); 71 | 72 | if( strchr( arg1, ';' ) || strchr( arg2, ';' ) || !is_good_string(arg1) || !is_good_string(arg2)) { 73 | SV_SendServerCommand(cl, 0, "e \"GAME_INVALIDVOTESTRING\""); 74 | return; 75 | } 76 | 77 | if ( Q_stricmp(arg1, "map_restart") 78 | && Q_stricmp(arg1, "map_rotate") 79 | && Q_stricmp(arg1, "typemap") 80 | && Q_stricmp(arg1, "map") 81 | && Q_stricmp(arg1, "g_gametype") 82 | && Q_stricmp(arg1, "kick") 83 | && Q_stricmp(arg1, "clientkick") ) { 84 | SV_SendServerCommand(cl, 0, "e \"GAME_INVALIDVOTESTRING\""); 85 | return; 86 | } 87 | 88 | if(*(int*)(&level[2844])) { 89 | *(int*)&level[2844] = 0; 90 | SV_SendServerCommand(cl, 0, "e \"Invalid.\""); 91 | return; 92 | } 93 | 94 | if(!Q_stricmp(arg1, "typemap")) { 95 | if(!Script_IsValidGametype(arg2)) { 96 | SV_SendServerCommand(cl, 0, "e \"GAME_INVALIDGAMETYPE\""); 97 | return; 98 | } 99 | 100 | if(!Q_stricmp(arg2, g_gametype->string 101 | }*/ 102 | } 103 | 104 | 105 | void G_SayTo( int *ent, int *other, int mode, int color, const char *name, const char *message ) { 106 | cvar_t* x_deadchat = Cvar_Get("x_deadchat", "1", 0); 107 | 108 | if(!call_onsameteam) 109 | call_onsameteam = GAME("OnSameTeam"); 110 | 111 | qboolean (*OnSameTeam)(int*, int*); 112 | *(int*)&OnSameTeam = call_onsameteam; 113 | 114 | 115 | if ( other ) { 116 | if ( *(unsigned char *)(other + 352)) { 117 | int v6 = *(int *)(other + 344); 118 | if (v6) { 119 | if ( *(int *)(v6 + 8428) == 2 || x_deadchat->integer == 1) { 120 | if ( mode != 1 || OnSameTeam(ent, other) ) 121 | { 122 | if ( !*(int *)(*(int *)(ent + 344) + 8400) || *(int*)(*(int *)(other + 344) + 8400) ) 123 | { 124 | SV_SendServerCommand(getclient(*other), 0, va("%s \"", (mode==1) ? "i" : "h", name, '^', color, message)); 125 | } 126 | } 127 | } 128 | } 129 | } 130 | } 131 | } 132 | 133 | --------------------------------------------------------------------------------