Merge branch 'next' of https://git.magicalgirl.moe/STJr/SRB2 into playercmd-kart-port

This commit is contained in:
Zachary McAlpin 2020-07-25 20:06:12 -05:00
commit 117943012a
23 changed files with 369 additions and 164 deletions

View File

@ -12,14 +12,15 @@
# to avoid a false positive with the version detection...
SUPPORTED_GCC_VERSIONS:=\
91\
81 82 83\
71 72\
101 102\
91 92 93\
81 82 83 84\
71 72 73 74 75\
61 62 63 64\
51 52 53 54\
51 52 53 54 55\
40 41 42 43 44 45 46 47 48 49
LATEST_GCC_VERSION=9.1
LATEST_GCC_VERSION=10.2
# gcc or g++
ifdef PREFIX
@ -68,7 +69,27 @@ ifeq (,$(filter GCC%,$(.VARIABLES)))
endif
endif
ifdef GCC102
GCC101=1
endif
ifdef GCC101
GCC93=1
endif
ifdef GCC93
GCC92=1
endif
ifdef GCC92
GCC91=1
endif
ifdef GCC91
GCC84=1
endif
ifdef GCC84
GCC83=1
endif
@ -81,6 +102,18 @@ GCC81=1
endif
ifdef GCC81
GCC75=1
endif
ifdef GCC75
GCC74=1
endif
ifdef GCC74
GCC73=1
endif
ifdef GCC73
GCC72=1
endif
@ -105,6 +138,10 @@ GCC61=1
endif
ifdef GCC61
GCC55=1
endif
ifdef GCC55
GCC54=1
endif

View File

@ -3615,6 +3615,9 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
CL_RemovePlayer(pnum, kickreason);
}
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
@ -5380,6 +5383,10 @@ void TryRunTics(tic_t realtics)
ExtraDataTicker();
gametic++;
consistancy[gametic%BACKUPTICS] = Consistancy();
// Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame.
if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value)
break;
}
}
}

View File

@ -540,7 +540,7 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
extern consvar_t cv_resynchattempts, cv_blamecfail;
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;

View File

@ -701,6 +701,7 @@ void D_RegisterClientCommands(void)
#endif
CV_RegisterVar(&cv_rollingdemos);
CV_RegisterVar(&cv_netstat);
CV_RegisterVar(&cv_netticbuffer);
#ifdef NETGAME_DEVMODE
CV_RegisterVar(&cv_fishcake);

View File

@ -808,9 +808,11 @@ static void readskincolor(MYFILE *f, INT32 num)
{
size_t namesize = sizeof(skincolors[num].name);
char truncword[namesize];
UINT16 dupecheck;
deh_strlcpy(truncword, word2, namesize, va("Skincolor %d: name", num)); // truncate here to check for dupes
if (truncword[0] != '\0' && (!stricmp(truncword, skincolors[SKINCOLOR_NONE].name) || R_GetColorByName(truncword)))
dupecheck = R_GetColorByName(truncword);
if (truncword[0] != '\0' && (!stricmp(truncword, skincolors[SKINCOLOR_NONE].name) || (dupecheck && dupecheck != num)))
{
size_t lastchar = strlen(truncword);
char oldword[lastchar+1];
@ -4726,11 +4728,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
{
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_skincolor(word2); // find a skincolor by name
if (i < numskincolors && i >= (INT32)SKINCOLOR_FIRSTFREESLOT)
if (i && i < numskincolors)
readskincolor(f, i);
else
{
deh_warning("Skincolor %d out of range (%d - %d)", i, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
deh_warning("Skincolor %d out of range (1 - %d)", i, numskincolors-1);
ignorelines(f);
}
}

View File

@ -2382,9 +2382,12 @@ static void WriteDemoChecksum(void)
static void G_StopDemoRecording(void)
{
boolean saved = false;
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
WriteDemoChecksum();
saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file.
if (demo_p)
{
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
WriteDemoChecksum();
saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file.
}
free(demobuffer);
demorecording = false;

View File

@ -214,6 +214,9 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
poly_color.s.blue = (UINT8)blue;
}
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
light_level = min(max(light_level, 0), 255);
Surface->PolyColor.rgba = poly_color.rgba;
Surface->TintColor.rgba = tint_color.rgba;
Surface->FadeColor.rgba = fade_color.rgba;
@ -2757,8 +2760,11 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
HWR_SetCurrentTexture(NULL);
// reference point for flat texture coord for each vertex around the polygon
flatxref = (float)((polysector->origVerts[0].x & (~flatflag)) / fflatwidth);
flatyref = (float)((polysector->origVerts[0].y & (~flatflag)) / fflatheight);
flatxref = FIXED_TO_FLOAT(polysector->origVerts[0].x);
flatyref = FIXED_TO_FLOAT(polysector->origVerts[0].y);
flatxref = (float)(((fixed_t)flatxref & (~flatflag)) / fflatwidth);
flatyref = (float)(((fixed_t)flatyref & (~flatflag)) / fflatheight);
// transform
v3d = planeVerts;

View File

@ -1535,7 +1535,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
break;
default : // must be 0, otherwise it's an error
// No blending

View File

@ -1116,6 +1116,16 @@ static int lib_pPlayerCanDamage(lua_State *L)
return 1;
}
static int lib_pPlayerFullbright(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushboolean(L, P_PlayerFullbright(player));
return 1;
}
static int lib_pIsObjectInGoop(lua_State *L)
{
@ -3119,6 +3129,117 @@ static int lib_gBuildMapTitle(lua_State *L)
return 1;
}
static void
Lpushdim (lua_State *L, int c, struct searchdim *v)
{
int i;
lua_createtable(L, c, 0);/* I guess narr is numeric indices??? */
for (i = 0; i < c; ++i)
{
lua_createtable(L, 0, 2);/* and hashed indices (field)... */
lua_pushnumber(L, v[i].pos);
lua_setfield(L, -2, "pos");
lua_pushnumber(L, v[i].siz);
lua_setfield(L, -2, "siz");
lua_rawseti(L, -2, 1 + i);
}
}
/*
I decided to make this return a table because userdata
is scary and tables let the user set their own fields.
*/
/*
Returns:
[1] => map number
[2] => map title
[3] => search frequency table
The frequency table is unsorted. It has the following format:
{
['mapnum'],
['matchd'] => matches in map title string
['keywhd'] => matches in map keywords
The above two tables have the following format:
{
['pos'] => offset from start of string
['siz'] => length of match
}...
['total'] => the total matches
}...
*/
static int lib_gFindMap(lua_State *L)
{
const char *query = luaL_checkstring(L, 1);
INT32 map;
char *realname;
INT32 frc;
mapsearchfreq_t *frv;
INT32 i;
map = G_FindMap(query, &realname, &frv, &frc);
lua_settop(L, 0);
lua_pushnumber(L, map);
lua_pushstring(L, realname);
lua_createtable(L, frc, 0);
for (i = 0; i < frc; ++i)
{
lua_createtable(L, 0, 4);
lua_pushnumber(L, frv[i].mapnum);
lua_setfield(L, -2, "mapnum");
Lpushdim(L, frv[i].matchc, frv[i].matchd);
lua_setfield(L, -2, "matchd");
Lpushdim(L, frv[i].keywhc, frv[i].keywhd);
lua_setfield(L, -2, "keywhd");
lua_pushnumber(L, frv[i].total);
lua_setfield(L, -2, "total");
lua_rawseti(L, -2, 1 + i);
}
G_FreeMapSearch(frv, frc);
Z_Free(realname);
return 3;
}
/*
Returns:
[1] => map number
[2] => map title
*/
static int lib_gFindMapByNameOrCode(lua_State *L)
{
const char *query = luaL_checkstring(L, 1);
INT32 map;
char *realname;
map = G_FindMapByNameOrCode(query, &realname);
lua_pushnumber(L, map);
if (map)
{
lua_pushstring(L, realname);
Z_Free(realname);
return 2;
}
else
return 1;
}
static int lib_gDoReborn(lua_State *L)
{
INT32 playernum = luaL_checkinteger(L, 1);
@ -3389,6 +3510,7 @@ static luaL_Reg lib[] = {
{"P_DoPlayerPain",lib_pDoPlayerPain},
{"P_ResetPlayer",lib_pResetPlayer},
{"P_PlayerCanDamage",lib_pPlayerCanDamage},
{"P_PlayerFullbright",lib_pPlayerFullbright},
{"P_IsObjectInGoop",lib_pIsObjectInGoop},
{"P_IsObjectOnGround",lib_pIsObjectOnGround},
{"P_InSpaceSector",lib_pInSpaceSector},
@ -3531,6 +3653,8 @@ static luaL_Reg lib[] = {
{"G_AddGametype", lib_gAddGametype},
{"G_BuildMapName",lib_gBuildMapName},
{"G_BuildMapTitle",lib_gBuildMapTitle},
{"G_FindMap",lib_gFindMap},
{"G_FindMapByNameOrCode",lib_gFindMapByNameOrCode},
{"G_DoReborn",lib_gDoReborn},
{"G_SetCustomExitVars",lib_gSetCustomExitVars},
{"G_EnoughPlayersFinished",lib_gEnoughPlayersFinished},

View File

@ -1514,7 +1514,7 @@ static void setRamp(lua_State *L, skincolor_t* c) {
UINT32 i;
lua_pushnil(L);
for (i=0; i<COLORRAMPSIZE; i++) {
if (lua_objlen(L,-2)<COLORRAMPSIZE) {
if (lua_objlen(L,-2)!=COLORRAMPSIZE) {
luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' must be %d entries long; got %d.", COLORRAMPSIZE, lua_objlen(L,-2));
break;
}
@ -1536,8 +1536,8 @@ static int lib_setSkinColor(lua_State *L)
lua_remove(L, 1); // don't care about skincolors[] userdata.
{
cnum = (UINT16)luaL_checkinteger(L, 1);
if (cnum < SKINCOLOR_FIRSTFREESLOT || cnum >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
if (!cnum || cnum >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", cnum, numskincolors-1);
info = &skincolors[cnum]; // get the skincolor to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
@ -1588,14 +1588,19 @@ static int lib_setSkinColor(lua_State *L)
} else if (i == 3 || (str && fastcmp(str,"invcolor"))) {
UINT16 v = (UINT16)luaL_checkinteger(L, 3);
if (v >= numskincolors)
return luaL_error(L, "attempt to set skincolors[%d].invcolor to out of range value %d.", cnum, v);
return luaL_error(L, "skincolor_t field 'invcolor' out of range (1 - %d)", numskincolors-1);
info->invcolor = v;
} else if (i == 4 || (str && fastcmp(str,"invshade")))
info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE;
else if (i == 5 || (str && fastcmp(str,"chatcolor")))
info->chatcolor = (UINT16)luaL_checkinteger(L, 3);
else if (i == 6 || (str && fastcmp(str,"accessible")))
info->accessible = lua_toboolean(L, 3);
else if (i == 6 || (str && fastcmp(str,"accessible"))) {
boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
else
info->accessible = v;
}
lua_pop(L, 1);
}
return 0;
@ -1640,12 +1645,13 @@ static int skincolor_set(lua_State *L)
UINT32 i;
skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR));
const char *field = luaL_checkstring(L, 2);
UINT16 cnum = (UINT16)(info-skincolors);
I_Assert(info != NULL);
I_Assert(info >= skincolors);
if (info-skincolors < SKINCOLOR_FIRSTFREESLOT || info-skincolors >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", info-skincolors, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
if (!cnum || cnum >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", cnum, numskincolors-1);
if (fastcmp(field,"name")) {
const char* n = luaL_checkstring(L, 3);
@ -1658,7 +1664,7 @@ static int skincolor_set(lua_State *L)
if (info->name[0] != '\0') // don't check empty string for dupe
{
UINT16 dupecheck = R_GetColorByName(info->name);
if (!stricmp(info->name, skincolors[SKINCOLOR_NONE].name) || (dupecheck && (dupecheck != info-skincolors)))
if (!stricmp(info->name, skincolors[SKINCOLOR_NONE].name) || (dupecheck && (dupecheck != cnum)))
CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') is a duplicate of another skincolor's name.\n", info->name);
}
} else if (fastcmp(field,"ramp")) {
@ -1669,19 +1675,23 @@ static int skincolor_set(lua_State *L)
else
for (i=0; i<COLORRAMPSIZE; i++)
info->ramp[i] = (*((UINT8 **)luaL_checkudata(L, 3, META_COLORRAMP)))[i];
skincolor_modified[info-skincolors] = true;
skincolor_modified[cnum] = true;
} else if (fastcmp(field,"invcolor")) {
UINT16 v = (UINT16)luaL_checkinteger(L, 3);
if (v >= numskincolors)
return luaL_error(L, "attempt to set skincolor_t field 'invcolor' to out of range value %d.", v);
return luaL_error(L, "skincolor_t field 'invcolor' out of range (1 - %d)", numskincolors-1);
info->invcolor = v;
} else if (fastcmp(field,"invshade"))
info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE;
else if (fastcmp(field,"chatcolor"))
info->chatcolor = (UINT16)luaL_checkinteger(L, 3);
else if (fastcmp(field,"accessible"))
info->accessible = lua_toboolean(L, 3);
else
else if (fastcmp(field,"accessible")) {
boolean v = lua_toboolean(L, 3);
if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible)
return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum);
else
info->accessible = v;
} else
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field);
return 1;
}
@ -1713,11 +1723,11 @@ static int colorramp_get(lua_State *L)
static int colorramp_set(lua_State *L)
{
UINT8 *colorramp = *((UINT8 **)luaL_checkudata(L, 1, META_COLORRAMP));
UINT16 cnum = (UINT16)(((uint8_t*)colorramp - (uint8_t*)(skincolors[0].ramp))/sizeof(skincolor_t));
UINT16 cnum = (UINT16)(((UINT8*)colorramp - (UINT8*)(skincolors[0].ramp))/sizeof(skincolor_t));
UINT32 n = luaL_checkinteger(L, 2);
UINT8 i = (UINT8)luaL_checkinteger(L, 3);
if (cnum < SKINCOLOR_FIRSTFREESLOT || cnum >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1);
if (!cnum || cnum >= numskincolors)
return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", cnum, numskincolors-1);
if (n >= COLORRAMPSIZE)
return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' index %d out of range (0 - %d)", n, COLORRAMPSIZE-1);
if (hud_running)

View File

@ -1482,21 +1482,23 @@ static menuitem_t OP_OpenGLLightingMenu[] =
static menuitem_t OP_SoundOptionsMenu[] =
{
{IT_HEADER, NULL, "Game Audio", NULL, 0},
{IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 12},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 22},
{IT_STRING | IT_CVAR, NULL, "Sound Effects", &cv_gamesounds, 6},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Sound Volume", &cv_soundvolume, 11},
{IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 42},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 52},
{IT_STRING | IT_CVAR, NULL, "Digital Music", &cv_gamedigimusic, 21},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Digital Music Volume", &cv_digmusicvolume, 26},
{IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 72},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 82},
{IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 36},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41},
{IT_STRING | IT_CVAR, NULL, "Music Preference", &cv_musicpref, 51},
{IT_HEADER, NULL, "Miscellaneous", NULL, 102},
{IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 114},
{IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 124},
{IT_STRING | IT_CVAR, NULL, "Default 1-Up sound", &cv_1upsound, 134},
{IT_HEADER, NULL, "Miscellaneous", NULL, 61},
{IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 67},
{IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 72},
{IT_STRING | IT_CVAR, NULL, "Default 1-Up sound", &cv_1upsound, 77},
{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 154},
{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 87},
};
#ifdef HAVE_OPENMPT
@ -2195,7 +2197,7 @@ menu_t OP_ColorOptionsDef =
0,
NULL
};
menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE(
menu_t OP_SoundOptionsDef = DEFAULTSCROLLMENUSTYLE(
MTREE2(MN_OP_MAIN, MN_OP_SOUND),
"M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30);
menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(

View File

@ -142,6 +142,7 @@ void P_SetPlayerAngle(player_t *player, angle_t angle);
angle_t P_GetLocalAngle(player_t *player);
void P_SetLocalAngle(player_t *player, angle_t angle);
void P_ForceLocalAngle(player_t *player, angle_t angle);
boolean P_PlayerFullbright(player_t *player);
boolean P_IsObjectInGoop(mobj_t *mo);
boolean P_IsObjectOnGround(mobj_t *mo);

View File

@ -442,7 +442,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
mobj->sprite2 = spr2;
mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
if (player->powers[pw_super] || (player->powers[pw_carry] == CR_NIGHTSMODE && (player->charflags & (SF_SUPER|SF_NONIGHTSSUPER)) == SF_SUPER)) // Super colours? Super bright!
if (P_PlayerFullbright(player))
mobj->frame |= FF_FULLBRIGHT;
}
// Regular sprites

View File

@ -355,8 +355,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->mustrack = 0;
mapheaderinfo[num]->muspos = 0;
mapheaderinfo[num]->musinterfadeout = 0;
mapheaderinfo[num]->musintername[0] = '\0';
mapheaderinfo[num]->muspostbossname[6] = 0;
mapheaderinfo[num]->musintername[0] = 0;
mapheaderinfo[num]->muspostbossname[0] = 0;
mapheaderinfo[num]->muspostbosstrack = 0;
mapheaderinfo[num]->muspostbosspos = 0;
mapheaderinfo[num]->muspostbossfadein = 0;

View File

@ -5536,7 +5536,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
if ((!(gametyperules & GTR_TEAMFLAGS) || !player->gotflag) && !player->exiting)
{
if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP)
if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP && player->charability != CA_THOK)
{
fixed_t potentialmomz;
if (player->charability == CA_SLOWFALL)
@ -7975,20 +7975,13 @@ void P_MovePlayer(player_t *player)
// Locate the capsule for this mare.
else if (maptol & TOL_NIGHTS)
{
if ((player->powers[pw_carry] == CR_NIGHTSMODE)
&& (player->exiting
|| !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state < &states[S_PLAY_NIGHTS_TRANS6]))) // Note the < instead of <=
if (P_PlayerFullbright(player))
{
skin_t *skin = ((skin_t *)(player->mo->skin));
if (( skin->flags & (SF_SUPER|SF_NONIGHTSSUPER) ) == SF_SUPER)
{
player->mo->color = skin->supercolor
+ ((player->nightstime == player->startedtime)
? 4
: abs((((signed)leveltime >> 1) % 9) - 4)); // This is where super flashing is handled.
G_GhostAddColor(GHC_SUPER);
}
player->mo->color = ((skin_t *)player->mo->skin)->supercolor
+ ((player->nightstime == player->startedtime)
? 4
: abs((((signed)leveltime >> 1) % 9) - 4)); // This is where super flashing is handled.
G_GhostAddColor(GHC_SUPER);
}
if (!player->capsule && !player->bonustime)
@ -12895,3 +12888,12 @@ void P_ForceLocalAngle(player_t *player, angle_t angle)
else if (player == &players[secondarydisplayplayer])
localangle2 = angle;
}
boolean P_PlayerFullbright(player_t *player)
{
return (player->powers[pw_super]
|| ((player->powers[pw_carry] == CR_NIGHTSMODE && (((skin_t *)player->mo->skin)->flags & (SF_SUPER|SF_NONIGHTSSUPER)) == SF_SUPER) // Super colours? Super bright!
&& (player->exiting
|| !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state < &states[S_PLAY_NIGHTS_TRANS6])))); // Note the < instead of <=
}

View File

@ -60,6 +60,7 @@ static void Command_RestartAudio_f(void);
static void GameMIDIMusic_OnChange(void);
static void GameSounds_OnChange(void);
static void GameDigiMusic_OnChange(void);
static void MusicPref_OnChange(void);
#ifdef HAVE_OPENMPT
static void ModFilter_OnChange(void);
@ -129,6 +130,14 @@ consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O
consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
// Music preference
static CV_PossibleValue_t cons_musicpref_t[] = {
{0, "Digital"},
{1, "MIDI"},
{0, NULL}
};
consvar_t cv_musicpref = {"musicpref", "Digital", CV_SAVE|CV_CALL|CV_NOINIT, cons_musicpref_t, MusicPref_OnChange, 0, NULL, NULL, 0, 0, NULL};
// Window focus sound sytem toggles
consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -301,6 +310,7 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&cv_gamesounds);
CV_RegisterVar(&cv_gamedigimusic);
CV_RegisterVar(&cv_gamemidimusic);
CV_RegisterVar(&cv_musicpref);
#ifdef HAVE_OPENMPT
CV_RegisterVar(&cv_modfilter);
#endif
@ -1847,19 +1857,6 @@ const char *S_MusicName(void)
return music_name;
}
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
{
if (!I_SongPlaying())
return false;
strncpy(mname, music_name, 7);
mname[6] = 0;
*mflags = music_flags;
*looping = music_looping;
return (boolean)mname[0];
}
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi)
{
return (
@ -2100,6 +2097,8 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
boolean mapmuschanged = false;
musicstack_t *result;
musicstack_t *entry = Z_Calloc(sizeof (*result), PU_MUSIC, NULL);
boolean currentmidi = (I_SongType() == MU_MID || I_SongType() == MU_MID_EX);
boolean midipref = cv_musicpref.value;
if (status)
result = S_GetMusicStackEntry(status, fromfirst, -1);
@ -2154,7 +2153,8 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
return false;
}
if (strncmp(entry->musname, S_MusicName(), 7)) // don't restart music if we're already playing it
if (strncmp(entry->musname, S_MusicName(), 7) || // don't restart music if we're already playing it
(midipref != currentmidi && S_PrefAvailable(midipref, entry->musname))) // but do if the user's preference has changed
{
if (music_stack_fadeout)
S_ChangeMusicEx(entry->musname, entry->musflags, entry->looping, 0, music_stack_fadeout, 0);
@ -2201,10 +2201,12 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
static lumpnum_t S_GetMusicLumpNum(const char *mname)
{
if (!S_DigMusicDisabled() && S_DigExists(mname))
return W_GetNumForName(va("o_%s", mname));
else if (!S_MIDIMusicDisabled() && S_MIDIExists(mname))
return W_GetNumForName(va("d_%s", mname));
boolean midipref = cv_musicpref.value;
if (S_PrefAvailable(midipref, mname))
return W_GetNumForName(va(midipref ? "d_%s":"o_%s", mname));
else if (S_PrefAvailable(!midipref, mname))
return W_GetNumForName(va(midipref ? "o_%s":"d_%s", mname));
else
return LUMPERROR;
}
@ -2330,6 +2332,8 @@ static void S_ChangeMusicToQueue(void)
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms)
{
char newmusic[7];
boolean currentmidi = (I_SongType() == MU_MID || I_SongType() == MU_MID_EX);
boolean midipref = cv_musicpref.value;
if (S_MusicDisabled())
return;
@ -2359,7 +2363,8 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
I_FadeSong(0, prefadems, S_ChangeMusicToQueue);
return;
}
else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET))
else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET) ||
(midipref != currentmidi && S_PrefAvailable(midipref, newmusic)))
{
CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic);
@ -2665,32 +2670,24 @@ void GameDigiMusic_OnChange(void)
digital_disabled = false;
I_StartupSound(); // will return early if initialised
I_InitMusic();
S_StopMusic();
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
else if ((!cv_musicpref.value || midi_disabled) && S_DigExists("_clear"))
S_ChangeMusicInternal("_clear", false);
}
else
{
digital_disabled = true;
if (S_MusicType() != MU_MID)
if (S_MusicType() != MU_MID && S_MusicType() != MU_MID_EX)
{
if (midi_disabled)
S_StopMusic();
else
S_StopMusic();
if (!midi_disabled)
{
char mmusic[7];
UINT16 mflags;
boolean looping;
if (S_MusicInfo(mmusic, &mflags, &looping) && S_MIDIExists(mmusic))
{
S_StopMusic();
S_ChangeMusic(mmusic, mflags, looping);
}
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
S_StopMusic();
S_ChangeMusicInternal("_clear", false);
}
}
}
@ -2708,9 +2705,10 @@ void GameMIDIMusic_OnChange(void)
midi_disabled = false;
I_StartupSound(); // will return early if initialised
I_InitMusic();
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
else if ((cv_musicpref.value || digital_disabled) && S_MIDIExists("_clear"))
S_ChangeMusicInternal("_clear", false);
}
else
@ -2718,26 +2716,30 @@ void GameMIDIMusic_OnChange(void)
midi_disabled = true;
if (S_MusicType() == MU_MID || S_MusicType() == MU_MID_EX)
{
if (digital_disabled)
S_StopMusic();
else
S_StopMusic();
if (!digital_disabled)
{
char mmusic[7];
UINT16 mflags;
boolean looping;
if (S_MusicInfo(mmusic, &mflags, &looping) && S_DigExists(mmusic))
{
S_StopMusic();
S_ChangeMusic(mmusic, mflags, looping);
}
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
S_StopMusic();
S_ChangeMusicInternal("_clear", false);
}
}
}
}
void MusicPref_OnChange(void)
{
if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio") ||
M_CheckParm("-nomidimusic") || M_CheckParm("-nodigmusic"))
return;
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else if (S_PrefAvailable(cv_musicpref.value, "_clear"))
S_ChangeMusicInternal("_clear", false);
}
#ifdef HAVE_OPENMPT
void ModFilter_OnChange(void)
{

View File

@ -46,6 +46,7 @@ extern consvar_t cv_1upsound;
extern consvar_t cv_gamedigimusic;
extern consvar_t cv_gamemidimusic;
extern consvar_t cv_gamesounds;
extern consvar_t cv_musicpref;
extern consvar_t cv_playmusicifunfocused;
extern consvar_t cv_playsoundsifunfocused;
@ -178,11 +179,16 @@ boolean S_MusicPaused(void);
boolean S_MusicNotInFocus(void);
musictype_t S_MusicType(void);
const char *S_MusicName(void);
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
#define S_DigExists(a) S_MusicExists(a, false, true)
#define S_MIDIExists(a) S_MusicExists(a, true, false)
// Returns whether the preferred format a (true = MIDI, false = Digital)
// exists and is enabled for musicname b
#define S_PrefAvailable(a, b) (a ? \
(!S_MIDIMusicDisabled() && S_MIDIExists(b)) : \
(!S_DigMusicDisabled() && S_DigExists(b)))
//
// Music Effects
//

View File

@ -141,7 +141,6 @@ static y_data data;
// graphics
static patch_t *bgpatch = NULL; // INTERSCR
static patch_t *widebgpatch = NULL; // INTERSCW
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
static patch_t *interpic = NULL; // custom picture defined in map header
static boolean usetile;
@ -330,7 +329,7 @@ void Y_IntermissionDrawer(void)
safetorender = false;
}
if (!usebuffer || !safetorender)
if (!safetorender)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
if (!safetorender)
@ -359,12 +358,11 @@ void Y_IntermissionDrawer(void)
else if (rendermode != render_soft && usebuffer)
HWR_DrawIntermissionBG();
#endif
else
else if (bgpatch)
{
if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400)
V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch);
else if (bgpatch)
V_DrawScaledPatch(0, 0, 0, bgpatch);
fixed_t hs = vid.width * FRACUNIT / BASEVIDWIDTH;
fixed_t vs = vid.height * FRACUNIT / BASEVIDHEIGHT;
V_DrawStretchyFixedPatch(0, 0, hs, vs, V_NOSCALEPATCH, bgpatch, NULL);
}
}
else if (bgtile)
@ -1266,7 +1264,6 @@ void Y_StartIntermission(void)
data.coop.actnum = mapheaderinfo[gamemap-1]->actnum;
// get background patches
widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH);
bgpatch = W_CachePatchName("INTERSCR", PU_PATCH);
// grab an interscreen if appropriate
@ -2084,7 +2081,6 @@ static void Y_UnloadData(void)
// unload the background patches
UNLOAD(bgpatch);
UNLOAD(widebgpatch);
UNLOAD(bgtile);
UNLOAD(interpic);
@ -2127,7 +2123,6 @@ static void Y_CleanupData(void)
{
// unload the background patches
CLEANUP(bgpatch);
CLEANUP(widebgpatch);
CLEANUP(bgtile);
CLEANUP(interpic);

View File

@ -1,4 +1,4 @@
/client
/server
/server.log
/*.o
/*.log
/*.o

View File

@ -140,8 +140,8 @@ typedef struct
char port[8];
char name[32];
INT32 room;
char key[32]; // Secret key for linking dedicated servers to accounts
char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31)
char key[32]; // Secret key for linking dedicated servers to accounts
} ATTRPACK msg_server_t;
typedef struct

View File

@ -5,9 +5,10 @@
# Get LSB functions
. /lib/lsb/init-functions
. /etc/default/rcS
#. /etc/default/rcS
SRB2MS=/usr/local/bin/masterserver
#SRB2MS=/usr/local/bin/masterserver
SRB2MS=./server
SRB2MS_PORT=28900
# Check that the package is still installed
@ -15,11 +16,9 @@ SRB2MS_PORT=28900
case "$1" in
start)
log_begin_msg "Starting SRB2MS..."
log_begin_msg "Starting SRB2MS...\n"
umask 002
if start-stop-daemon --start \
--exec $SRB2MS \
-- $SRB2MS_PORT; then
if exec $SRB2MS $SRB2MS_PORT & then
log_end_msg 0
else
log_end_msg $?
@ -27,11 +26,11 @@ case "$1" in
;;
stop)
log_begin_msg "Stopping SRB2MS..."
if start-stop-daemon --stop --exec $SRB2MS; then
log_end_msg 0
log_begin_msg "Stopping SRB2MS...\n"
if killall $SRB2MS -q & then
log_end_msg 0
else
log_end_msg $?
log_end_msg $?
fi
;;
@ -40,7 +39,7 @@ case "$1" in
;;
*)
e cho "Usage: /etc/init.d/masterserver {start|stop|restart|force-reload}"
echo "Usage: $0 {start|stop|restart|force-reload}"
exit 1
;;
esac

View File

@ -86,7 +86,7 @@ typedef struct
//=============================================================================
#define HOSTNAME "loopback"
#define HOSTNAME "localhost"
#define USER "srb2_ms"
#define PASSWORD "gLRDRb7WgLRDRb7W"
#define DATABASE "srb2_ms"
@ -291,17 +291,17 @@ void MySQL_AddServer(const char *ip, const char *port, const char *name, const c
char checkquery[500];
char updatequery[5000];
char queryp1[5000] = "INSERT INTO `ms_servers` (`name`,`ip`,`port`,`version`,`timestamp`,`room`,`key`) VALUES ('%s','%s','%s','%s','%ld','%d','%s')";
char checkqueryp1[500] = "SELECT room_override FROM `ms_servers` WHERE `ip` = '%s'";
char checkqueryp1[500] = "SELECT room_override FROM `ms_servers` WHERE `ip` = '%s' AND `port` = '%s'";
char updatequeryp1[5000];
if(firstadd)
{
logPrintf(logfile, "First add.\n");
strcpy(updatequeryp1, "UPDATE `ms_servers` SET `name` = '%s', `port` = '%s', `version` = '%s', timestamp = '%ld', upnow = '1', `room` = '%d', `delisted` = '0', `key` = '%s' WHERE `ip` = '%s'");
strcpy(updatequeryp1, "UPDATE `ms_servers` SET `name` = '%s', `port` = '%s', `version` = '%s', timestamp = '%ld', upnow = '1', `room` = '%d', `delisted` = '0', `key` = '%s' WHERE `ip` = '%s' AND `port` = '%s'");
}
else
{
logPrintf(logfile, "Update ping.\n");
strcpy(updatequeryp1, "UPDATE `ms_servers` SET `name` = '%s', `port` = '%s', `version` = '%s', timestamp = '%ld', upnow = '1', `room` = '%d', `key` = '%s' WHERE `ip` = '%s' AND `delisted` = '0'");
strcpy(updatequeryp1, "UPDATE `ms_servers` SET `name` = '%s', `port` = '%s', `version` = '%s', timestamp = '%ld', upnow = '1', `room` = '%d', `key` = '%s' WHERE `ip` = '%s' AND `port` = '%s' AND `delisted` = '0'");
}
MySQL_Conn(false);
mysql_real_escape_string(conn, escapedName, name, (unsigned long)strlen(name));
@ -314,10 +314,10 @@ void MySQL_AddServer(const char *ip, const char *port, const char *name, const c
logPrintf(errorfile, "IP %s tried to use the private room %d! THIS SHOULD NOT HAPPEN\n", ip, room);
return;
}
sprintf(checkquery, checkqueryp1, ip);
sprintf(checkquery, checkqueryp1, ip, port);
time_t timestamp;
timestamp = time (NULL);
logPrintf(logfile, "Checking for existing servers in table with the same IP...\n");
logPrintf(logfile, "Checking for existing servers in table with the same IP and port...\n");
logPrintf(mysqlfile, "Executing MySQL Query: %s\n", checkquery);
if(mysql_query(conn, checkquery)) {
logPrintf(errorfile, "MYSQL ERROR: %s\n", mysql_error(conn));
@ -341,9 +341,9 @@ void MySQL_AddServer(const char *ip, const char *port, const char *name, const c
if(atoi(row[0]) != 0)
room = atoi(row[0]);
mysql_free_result(res);
logPrintf(logfile, "Server's IP already exists, so let's just update it instead...\n");
logPrintf(logfile, "Server's IP and port already exists, so let's just update it instead...\n");
logPrintf(logfile, "Updating Server Data for %s\n", ip);
sprintf(updatequery, updatequeryp1, escapedName, escapedPort, escapedVersion, timestamp, room, escapedKey, ip);
sprintf(updatequery, updatequeryp1, escapedName, escapedPort, escapedVersion, timestamp, room, escapedKey, ip, port);
logPrintf(mysqlfile, "Executing MySQL Query: %s\n", updatequery);
if(mysql_query(conn, updatequery)) {
logPrintf(errorfile, "MYSQL ERROR: %s\n", mysql_error(conn));
@ -619,10 +619,10 @@ void MySQL_ListServServers(UINT32 id, UINT32 type, const char *ip) {
void MySQL_RemoveServer(char *ip, char *port, char *name, char *version) {
char escapedName[255];
char updatequery[5000];
char updatequeryp1[5000] = "UPDATE `ms_servers` SET upnow = '0' WHERE `ip` = '%s' AND `permanent` = '0'";
char updatequeryp1[5000] = "UPDATE `ms_servers` SET upnow = '0' WHERE `ip` = '%s' AND `port` = '%s' AND `permanent` = '0'";
MySQL_Conn(false);
mysql_real_escape_string(conn, escapedName, name, (unsigned long)strlen(name));
sprintf(updatequery, updatequeryp1, ip);
sprintf(updatequery, updatequeryp1, ip, port);
logPrintf(mysqlfile, "Executing MySQL Query: %s\n", updatequery);
if(mysql_query(conn, updatequery)) {
logPrintf(errorfile, "MYSQL ERROR: %s\n", mysql_error(conn));
@ -841,6 +841,10 @@ static void addServer(int id, char *buffer, bool firstadd)
info->port[sizeof (info->port)-1] = '\0';
info->name[sizeof (info->name)-1] = '\0';
info->version[sizeof (info->version)-1] = '\0';
logPrintf(logfile, "addServer(): Version = \"%s\"\n", info->version);
logPrintf(logfile, "addServer(): Key = \"%s\"\n", info->key);
// retrieve the true ip of the server
strcpy(info->ip, server_socket.getClientIP(id));
//strcpy(info->port, server_socket.getClientPort(id));
@ -995,7 +999,7 @@ int main(int argc, char *argv[])
if (server_socket.listen(argv[1]) < 0)
{
fprintf(stderr, "Error while initializing the server\n");
fprintf(stderr, "Error while initializing the server; port being used! Try killing the other Master Server.\n");
exit(2);
}

View File

@ -13,8 +13,8 @@ SET time_zone = "+00:00";
-- Database: `srb2ms`
--
CREATE DATABASE IF NOT EXISTS `srb2ms` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `srb2ms`;
CREATE DATABASE IF NOT EXISTS `srb2_ms` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `srb2_ms`;
-- --------------------------------------------------------
@ -25,8 +25,8 @@ USE `srb2ms`;
CREATE TABLE `ms_bans` (
`bid` int(11) DEFAULT NULL,
`ipstart` int(11) DEFAULT NULL,
`ipend` int(11) DEFAULT NULL,
`ipstart` int(10) unsigned DEFAULT NULL,
`ipend` int(10) unsigned DEFAULT NULL,
`full_endtime` int(11) DEFAULT NULL,
`permanent` tinyint(1) DEFAULT NULL,
`hostonly` tinyint(1) DEFAULT NULL,
@ -63,19 +63,19 @@ INSERT INTO `ms_rooms` (`room_id`, `title`, `motd`, `visible`, `order`, `private
--
CREATE TABLE `ms_servers` (
`sid` int(11) NOT NULL,
`sid` int(11) primary key AUTO_INCREMENT,
`name` text COLLATE utf8mb4_unicode_ci NOT NULL,
`ip` text COLLATE utf8mb4_unicode_ci NOT NULL,
`port` int(11) NOT NULL,
`port` int(11) NOT NULL DEFAULT 5029,
`version` text COLLATE utf8mb4_unicode_ci NOT NULL,
`timestamp` int(11) NOT NULL,
`room` int(11) NOT NULL,
`timestamp` int(11) NOT NULL DEFAULT 0,
`room` int(11) NOT NULL DEFAULT 0,
`key` text COLLATE utf8mb4_unicode_ci NOT NULL,
`room_override` int(11) NOT NULL,
`upnow` tinyint(1) NOT NULL,
`permanent` tinyint(1) NOT NULL,
`delisted` tinyint(1) NOT NULL,
`sticky` int(11) NOT NULL
`room_override` int(11) NOT NULL DEFAULT 0,
`upnow` tinyint(1) NOT NULL DEFAULT 1,
`permanent` tinyint(1) NOT NULL DEFAULT 0,
`delisted` tinyint(1) NOT NULL DEFAULT 0,
`sticky` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
@ -85,16 +85,20 @@ CREATE TABLE `ms_servers` (
--
CREATE TABLE `ms_versions` (
`mod_id` int(11) NOT NULL,
`mod_version` int(11) NOT NULL
`mod_id` int(10) unsigned primary key AUTO_INCREMENT,
`mod_version` int(10) unsigned NOT NULL DEFAULT 1,
`mod_vstring` varchar(45) NOT NULL DEFAULT 'v1.0',
`mod_codebase` int(10) unsigned NOT NULL DEFAULT 205,
`mod_name` varchar(255) NOT NULL DEFAULT 'Default MOD Name',
`mod_url` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `ms_versions`
--
INSERT INTO `ms_versions` (`mod_id`, `mod_version`) VALUES
(12, 25);
INSERT INTO `ms_versions` (`mod_id`, `mod_version`, `mod_vstring`, `mod_codebase`, `mod_name`, `mod_url`) VALUES
(18, 42, 'v2.2.2', 205, 'SRB2 2.2', 'SRB2.org');
-- --------------------------------------------------------
@ -114,4 +118,4 @@ COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;