[PATCH 1/2] Add patches to work around OA 0.8.1 to 0.8.5 network-compat breakage
Simon McVittie
smcv at debian.org
Sat Aug 21 15:09:09 UTC 2010
---
...NA_081_COMPATIBLE-define-for-network-comp.patch | 379 ++++++++++++++++++++
...arts-with-NTVE-followed-by-a-nonempty-str.patch | 53 +++
debian/patches/series | 2 +
3 files changed, 434 insertions(+), 0 deletions(-)
create mode 100644 debian/patches/0040-Add-OPENARENA_081_COMPATIBLE-define-for-network-comp.patch
create mode 100644 debian/patches/0041-If-a-QVM-starts-with-NTVE-followed-by-a-nonempty-str.patch
diff --git a/debian/patches/0040-Add-OPENARENA_081_COMPATIBLE-define-for-network-comp.patch b/debian/patches/0040-Add-OPENARENA_081_COMPATIBLE-define-for-network-comp.patch
new file mode 100644
index 0000000..bb6bd15
--- /dev/null
+++ b/debian/patches/0040-Add-OPENARENA_081_COMPATIBLE-define-for-network-comp.patch
@@ -0,0 +1,379 @@
+From aee4d733e1e9324e8392ecc0e024b50e3176b938 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv at debian.org>
+Date: Fri, 20 Aug 2010 23:27:28 +0100
+Subject: [PATCH] Add OPENARENA_081_COMPATIBLE define for network compat with 0.8.1
+
+0.8.1 was approximately compatible with Quake III Arena, whereas 0.8.5
+is more like Team Arena. Unfortunately, these are not the same.
+
+Bug: http://openarena.ws/board/index.php?topic=3717.0
+---
+ game/Makefile | 4 ++++
+ game/code/cgame/cg_draw.c | 6 +++---
+ game/code/game/ai_dmq3.c | 2 ++
+ game/code/game/bg_misc.c | 15 ++++++++++++---
+ game/code/game/bg_pmove.c | 2 ++
+ game/code/game/bg_public.h | 11 ++++++++++-
+ game/code/game/g_active.c | 11 ++++++++++-
+ game/code/game/g_combat.c | 4 ++++
+ game/code/game/g_items.c | 9 ++++++++-
+ 9 files changed, 55 insertions(+), 9 deletions(-)
+
+diff --git a/game/Makefile b/game/Makefile
+index 1520a96..f3dd3f1 100644
+--- a/game/Makefile
++++ b/game/Makefile
+@@ -852,6 +852,10 @@ endif
+
+ BASE_CFLAGS += -DPRODUCT_VERSION=\\\"$(VERSION)\\\"
+
++ifeq ($(OPENARENA_081_COMPATIBLE),1)
++ BASE_CFLAGS += -DOPENARENA_081_COMPATIBLE
++endif
++
+ ifeq ($(V),1)
+ echo_cmd=@:
+ Q=
+diff --git a/game/code/cgame/cg_draw.c b/game/code/cgame/cg_draw.c
+index e4d2b2a..32f74dd 100644
+--- a/game/code/cgame/cg_draw.c
++++ b/game/code/cgame/cg_draw.c
+@@ -1890,7 +1890,6 @@ static void CG_DrawHoldableItem( void ) {
+ }
+ #endif // MISSIONPACK
+
+-#ifndef MISSIONPACK
+ /*
+ ===================
+ CG_DrawPersistantPowerup
+@@ -1898,6 +1897,7 @@ CG_DrawPersistantPowerup
+ */
+ #if 1 // sos001208 - DEAD // sago - ALIVE
+ static void CG_DrawPersistantPowerup( void ) {
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ int value;
+
+ value = cg.snap->ps.stats[STAT_PERSISTANT_POWERUP];
+@@ -1905,9 +1905,9 @@ static void CG_DrawPersistantPowerup( void ) {
+ CG_RegisterItemVisuals( value );
+ CG_DrawPic( 640-ICON_SIZE, (SCREEN_HEIGHT-ICON_SIZE)/2 - ICON_SIZE, ICON_SIZE, ICON_SIZE, cg_items[ value ].icon );
+ }
++#endif
+ }
+ #endif
+-#endif // MISSIONPACK
+
+
+ /*
+@@ -3243,8 +3243,8 @@ static void CG_Draw2D(stereoFrame_t stereoFrame)
+
+ #ifndef MISSIONPACK
+ CG_DrawHoldableItem();
+- CG_DrawPersistantPowerup();
+ #endif
++ CG_DrawPersistantPowerup();
+
+ CG_DrawReward();
+ }
+diff --git a/game/code/game/ai_dmq3.c b/game/code/game/ai_dmq3.c
+index 9037445..9731fdd 100644
+--- a/game/code/game/ai_dmq3.c
++++ b/game/code/game/ai_dmq3.c
+@@ -1881,10 +1881,12 @@ void BotUpdateInventory(bot_state_t *bs) {
+ bs->inventory[INVENTORY_INVISIBILITY] = bs->cur_ps.powerups[PW_INVIS] != 0;
+ bs->inventory[INVENTORY_REGEN] = bs->cur_ps.powerups[PW_REGEN] != 0;
+ bs->inventory[INVENTORY_FLIGHT] = bs->cur_ps.powerups[PW_FLIGHT] != 0;
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ bs->inventory[INVENTORY_SCOUT] = bs->cur_ps.stats[STAT_PERSISTANT_POWERUP] == MODELINDEX_SCOUT;
+ bs->inventory[INVENTORY_GUARD] = bs->cur_ps.stats[STAT_PERSISTANT_POWERUP] == MODELINDEX_GUARD;
+ bs->inventory[INVENTORY_DOUBLER] = bs->cur_ps.stats[STAT_PERSISTANT_POWERUP] == MODELINDEX_DOUBLER;
+ bs->inventory[INVENTORY_AMMOREGEN] = bs->cur_ps.stats[STAT_PERSISTANT_POWERUP] == MODELINDEX_AMMOREGEN;
++#endif
+ bs->inventory[INVENTORY_REDFLAG] = bs->cur_ps.powerups[PW_REDFLAG] != 0;
+ bs->inventory[INVENTORY_BLUEFLAG] = bs->cur_ps.powerups[PW_BLUEFLAG] != 0;
+ bs->inventory[INVENTORY_NEUTRALFLAG] = bs->cur_ps.powerups[PW_NEUTRALFLAG] != 0;
+diff --git a/game/code/game/bg_misc.c b/game/code/game/bg_misc.c
+index 767cc7e..c701434 100644
+--- a/game/code/game/bg_misc.c
++++ b/game/code/game/bg_misc.c
+@@ -655,6 +655,7 @@ Only in CTF games
+ /* sounds */ ""
+ },
+
++#ifdef HAVE_MISSIONPACK_ITEMLIST
+ /*QUAKED holdable_kamikaze (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
+ */
+ {
+@@ -702,6 +703,7 @@ Only in CTF games
+ /* precache */ "",
+ /* sounds */ ""
+ },
++#endif
+
+ /*QUAKED ammo_nails (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
+ */
+@@ -751,6 +753,7 @@ Only in CTF games
+ /* sounds */ ""
+ },
+
++#ifdef HAVE_MISSIONPACK_ITEMLIST
+ //
+ // PERSISTANT POWERUP ITEMS
+ //
+@@ -817,6 +820,7 @@ Only in CTF games
+ /* precache */ "",
+ /* sounds */ ""
+ },
++#endif
+
+
+ /*QUAKED team_CTF_neutralflag (0 0 1) (-16 -16 -16) (16 16 16)
+@@ -1214,6 +1218,9 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
+ return qtrue;
+
+ case IT_ARMOR:
++ upperBound = ps->stats[STAT_MAX_HEALTH] * 2;
++
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
+ return qfalse;
+ }
+@@ -1222,9 +1229,7 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
+ if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
+ upperBound = ps->stats[STAT_MAX_HEALTH];
+ }
+- else {
+- upperBound = ps->stats[STAT_MAX_HEALTH] * 2;
+- }
++#endif
+
+ if ( ps->stats[STAT_ARMOR] >= upperBound ) {
+ return qfalse;
+@@ -1232,12 +1237,14 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
+ return qtrue;
+
+ case IT_HEALTH:
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ // small and mega healths will go over the max, otherwise
+ // don't pick up if already at max
+ if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
+ upperBound = ps->stats[STAT_MAX_HEALTH];
+ }
+ else
++#endif
+ if ( item->quantity == 5 || item->quantity == 100 ) {
+ if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
+ return qfalse;
+@@ -1253,6 +1260,7 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
+ case IT_POWERUP:
+ return qtrue; // powerups are always picked up
+
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ case IT_PERSISTANT_POWERUP:
+
+ //In Double D we don't want persistant Powerups (or maybe, can be discussed)
+@@ -1273,6 +1281,7 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
+ }
+
+ return qtrue;
++#endif
+
+ case IT_TEAM: // team items, such as flags
+ if( gametype == GT_1FCTF ) {
+diff --git a/game/code/game/bg_pmove.c b/game/code/game/bg_pmove.c
+index 8bb6a2c..2fd3ba5 100644
+--- a/game/code/game/bg_pmove.c
++++ b/game/code/game/bg_pmove.c
+@@ -1696,6 +1696,7 @@ static void PM_Weapon( void ) {
+ break;
+ }
+
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( bg_itemlist[pm->ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
+ addTime /= 1.5;
+ }
+@@ -1704,6 +1705,7 @@ static void PM_Weapon( void ) {
+ addTime /= 1.3;
+ }
+ else
++#endif
+ if ( pm->ps->powerups[PW_HASTE] ) {
+ addTime /= 1.3;
+ }
+diff --git a/game/code/game/bg_public.h b/game/code/game/bg_public.h
+index b0efb3e..3fcd777 100644
+--- a/game/code/game/bg_public.h
++++ b/game/code/game/bg_public.h
+@@ -25,6 +25,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ // because games can change separately from the main system version, we need a
+ // second version that must match between game and cgame
+
++#if defined(MISSIONPACK) || !defined(OPENARENA_081_COMPATIBLE)
++// MISSIONPACK and 0.8.5 break ABI and network compatibility, because
++// STAT_PERSISTANT_POWERUP wasn't added at the end of its enum. Sad times.
++# define HAVE_STAT_PERSISTANT_POWERUP
++// Adding objects to the middle of the bg_itemlist also breaks network compat.
++# define HAVE_MISSIONPACK_ITEMLIST
++#endif
++
+ #if defined(BG_PUBLIC_H)
+ #else
+ #define BG_PUBLIC_H 1
+@@ -223,13 +231,14 @@ void Pmove (pmove_t *pmove);
+
+ //===================================================================================
+
+-
+ // player_state->stats[] indexes
+ // NOTE: may not have more than 16
+ typedef enum {
+ STAT_HEALTH,
+ STAT_HOLDABLE_ITEM,
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ STAT_PERSISTANT_POWERUP,
++#endif
+ STAT_WEAPONS, // 16 bit fields
+ STAT_ARMOR,
+ STAT_DEAD_YAW, // look this direction when dead (FIXME: get rid of?)
+diff --git a/game/code/game/g_active.c b/game/code/game/g_active.c
+index c905261..b66f982 100644
+--- a/game/code/game/g_active.c
++++ b/game/code/game/g_active.c
+@@ -437,10 +437,13 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
+ continue;
+
+ // regenerate
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
+ maxHealth = client->ps.stats[STAT_MAX_HEALTH] / 2;
+ }
+- else if ( client->ps.powerups[PW_REGEN] ) {
++ else
++#endif
++ if ( client->ps.powerups[PW_REGEN] ) {
+ maxHealth = client->ps.stats[STAT_MAX_HEALTH];
+ }
+ else {
+@@ -484,6 +487,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
+ client->ps.stats[STAT_ARMOR]--;
+ }
+ }
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
+ int w, max, inc, t, i;
+ int weapList[]={WP_MACHINEGUN,WP_SHOTGUN,WP_GRENADE_LAUNCHER,WP_ROCKET_LAUNCHER,WP_LIGHTNING,WP_RAILGUN,WP_PLASMAGUN,WP_BFG,WP_NAILGUN,WP_PROX_LAUNCHER,WP_CHAINGUN};
+@@ -520,6 +524,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
+ }
+ }
+ }
++#endif
+ }
+
+ /*
+@@ -968,10 +973,12 @@ void ClientThink_real( gentity_t *ent ) {
+ // set speed
+ client->ps.speed = g_speed.value;
+
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
+ client->ps.speed *= 1.5;
+ }
+ else
++#endif
+ if ( client->ps.powerups[PW_HASTE] ) {
+ client->ps.speed *= 1.3;
+ }
+@@ -1278,6 +1285,7 @@ void ClientEndFrame( gentity_t *ent ) {
+ }
+
+ // set powerup for player animation
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
+ ent->client->ps.powerups[PW_GUARD] = level.time;
+ }
+@@ -1290,6 +1298,7 @@ void ClientEndFrame( gentity_t *ent ) {
+ if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
+ ent->client->ps.powerups[PW_AMMOREGEN] = level.time;
+ }
++#endif
+ if ( ent->client->invulnerabilityTime > level.time ) {
+ ent->client->ps.powerups[PW_INVULNERABILITY] = level.time;
+ }
+diff --git a/game/code/game/g_combat.c b/game/code/game/g_combat.c
+index 8c81284..22ce65a 100644
+--- a/game/code/game/g_combat.c
++++ b/game/code/game/g_combat.c
+@@ -227,7 +227,9 @@ void TossClientPersistantPowerups( gentity_t *ent ) {
+ powerup->r.contents = CONTENTS_TRIGGER;
+ trap_LinkEntity( powerup );
+
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ ent->client->ps.stats[STAT_PERSISTANT_POWERUP] = 0;
++#endif
+ ent->client->persistantPowerup = NULL;
+ }
+
+@@ -1071,9 +1073,11 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
+ // unless they are rocket jumping
+ if ( attacker->client && attacker != targ ) {
+ max = attacker->client->ps.stats[STAT_MAX_HEALTH];
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( bg_itemlist[attacker->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
+ max /= 2;
+ }
++#endif
+ damage = damage * max / 100;
+ }
+
+diff --git a/game/code/game/g_items.c b/game/code/game/g_items.c
+index cc003bc..1fd4619 100644
+--- a/game/code/game/g_items.c
++++ b/game/code/game/g_items.c
+@@ -118,6 +118,7 @@ int Pickup_Powerup( gentity_t *ent, gentity_t *other ) {
+ //======================================================================
+
+ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) {
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ int clientNum;
+ char userinfo[MAX_INFO_STRING];
+ float handicap;
+@@ -185,6 +186,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) {
+ break;
+ }
+
++#endif
+ return -1;
+ }
+
+@@ -277,11 +279,13 @@ int Pickup_Health (gentity_t *ent, gentity_t *other) {
+ int max;
+ int quantity;
+
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ // small and mega healths will go over the max
+ if( other->client && bg_itemlist[other->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
+ max = other->client->ps.stats[STAT_MAX_HEALTH];
+ }
+ else
++#endif
+ if ( ent->item->quantity != 5 && ent->item->quantity != 100 ) {
+ max = other->client->ps.stats[STAT_MAX_HEALTH];
+ } else {
+@@ -315,10 +319,13 @@ int Pickup_Armor( gentity_t *ent, gentity_t *other ) {
+
+ other->client->ps.stats[STAT_ARMOR] += ent->item->quantity;
+
++#ifdef HAVE_STAT_PERSISTANT_POWERUP
+ if( other->client && bg_itemlist[other->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
+ upperBound = other->client->ps.stats[STAT_MAX_HEALTH];
+ }
+- else {
++ else
++#endif
++ {
+ upperBound = other->client->ps.stats[STAT_MAX_HEALTH] * 2;
+ }
+
+--
+1.7.1
+
diff --git a/debian/patches/0041-If-a-QVM-starts-with-NTVE-followed-by-a-nonempty-str.patch b/debian/patches/0041-If-a-QVM-starts-with-NTVE-followed-by-a-nonempty-str.patch
new file mode 100644
index 0000000..66ce0bb
--- /dev/null
+++ b/debian/patches/0041-If-a-QVM-starts-with-NTVE-followed-by-a-nonempty-str.patch
@@ -0,0 +1,53 @@
+From 88632d58a1bb664b54621aac6bdf14b80315cfd9 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv at debian.org>
+Date: Sat, 21 Aug 2010 16:03:22 +0100
+Subject: [PATCH] If a QVM starts with NTVE followed by a nonempty string, look in that subdir
+
+This lets each version have a different substitute shared object, if
+necessary for network compatibility (OpenArena broke network
+compatibility between 0.8.1 and 0.8.5 by removing some #ifdef MISSIONPACK).
+---
+ engine/code/qcommon/vm.c | 20 ++++++++++++++++++++
+ 1 files changed, 20 insertions(+), 0 deletions(-)
+
+diff --git a/engine/code/qcommon/vm.c b/engine/code/qcommon/vm.c
+index 83832d1..2c1a7f5 100644
+--- a/engine/code/qcommon/vm.c
++++ b/engine/code/qcommon/vm.c
+@@ -372,6 +372,7 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
+ union {
+ vmHeader_t *h;
+ void *v;
++ char *s;
+ } header;
+
+ // load the image
+@@ -386,6 +387,25 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
+
+ if (LittleLong( header.h->vmMagic ) == VM_MAGIC_USE_NATIVE) {
+ Com_Printf( "...which has vmMagic VM_MAGIC_USE_NATIVE.\n" );
++
++ if (header.s[sizeof(int)] != '\0') {
++ Com_sprintf( filename, sizeof(filename), "%.*s/%s", length - sizeof(int), header.s + sizeof(int), vm->name );
++ filename[sizeof(filename)-1] = '\0';
++
++ if (FS_CheckDirTraversal( filename )) {
++ Com_Printf( "Directory traversal detected! %s", filename );
++ VM_Free( vm );
++ return NULL;
++ }
++
++ vm->dllHandle = Sys_LoadDll( filename, vm->fqpath , &vm->entryPoint, VM_DllSyscall );
++
++ if (vm->dllHandle != NULL) {
++ Com_Printf( "Loaded prefixed DLL file %s.\n", filename );
++ return header.h;
++ }
++ }
++
+ Com_Printf( "Loading DLL file %s instead.\n", vm->name );
+ vm->dllHandle = Sys_LoadDll( vm->name, vm->fqpath , &vm->entryPoint, VM_DllSyscall );
+ if ( !vm->dllHandle ) {
+--
+1.7.1
+
diff --git a/debian/patches/series b/debian/patches/series
index 4f37be5..485ad3a 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -31,3 +31,5 @@
0037-Put-a-error-marker-in-engine-s-ui_shared.h-to-make-s.patch
0038-Fix-buffer-overflow-report-and-patch-by-Eugene-C.-46.patch
0039-Used-self-enemy-before-it-was-initialized.-Might-hav.patch
+0040-Add-OPENARENA_081_COMPATIBLE-define-for-network-comp.patch
+0041-If-a-QVM-starts-with-NTVE-followed-by-a-nonempty-str.patch
--
1.7.1
--lrZ03NoBR/3+SXJZ
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0002-Install-0.8.1-compatible-binaries-to-a-subdirectory.patch"
More information about the Pkg-games-devel
mailing list