mirror of
https://git.code.sf.net/p/quake/quakeforge-old
synced 2024-11-22 11:51:17 +00:00
Some misc 3dfx changes..
Some keys changes for toggle console.. Some (not currently the /best/, but functional) speed cheat improvements.. And some stuff brought in from QuakeLives.. (max rate, and new ping system)
This commit is contained in:
parent
5f01b641b0
commit
c188df7698
8 changed files with 174 additions and 68 deletions
|
@ -30,19 +30,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/fxmesa.h>
|
||||
#include <glide/sst1vid.h>
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 200
|
||||
|
||||
|
||||
unsigned short d_8to16table[256];
|
||||
//unsigned short d_8to16table[256];
|
||||
unsigned d_8to24table[256];
|
||||
unsigned char d_15to8table[65536];
|
||||
unsigned char d_15to8table[65536];
|
||||
|
||||
static cvar_t vid_mode = {"vid_mode","5",false};
|
||||
static cvar_t vid_redrawfull = {"vid_redrawfull","0",false};
|
||||
static cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true};
|
||||
cvar_t gl_ztrick = {"gl_ztrick", "1", true};
|
||||
static cvar_t vid_mode = {"vid_mode", "5", false};
|
||||
static cvar_t vid_redrawfull = {"vid_redrawfull", "0", false};
|
||||
static cvar_t vid_waitforrefresh = {"vid_waitforrefresh", "0", true};
|
||||
cvar_t gl_ztrick = {"gl_ztrick", "0", true};
|
||||
|
||||
static fxMesaContext fc = NULL;
|
||||
static int scr_width, scr_height;
|
||||
|
@ -218,8 +219,6 @@ void GL_Init (void)
|
|||
gl_extensions = glGetString (GL_EXTENSIONS);
|
||||
Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
|
||||
|
||||
// Con_Printf ("%s %s\n", gl_renderer, gl_version);
|
||||
|
||||
glClearColor (1,0,0,0);
|
||||
glCullFace(GL_FRONT);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
@ -267,10 +266,30 @@ void GL_EndRendering (void)
|
|||
}
|
||||
|
||||
static int resolutions[][3]={
|
||||
{ 512, 384, GR_RESOLUTION_512x384 },
|
||||
{ 640, 400, GR_RESOLUTION_640x400 },
|
||||
{ 640, 480, GR_RESOLUTION_640x480 },
|
||||
{ 800, 600, GR_RESOLUTION_800x600 }
|
||||
{ 320, 200, GR_RESOLUTION_320x200 },
|
||||
{ 320, 240, GR_RESOLUTION_320x240 },
|
||||
{ 400, 256, GR_RESOLUTION_400x256 },
|
||||
{ 400, 300, GR_RESOLUTION_400x300 },
|
||||
{ 512, 256, GR_RESOLUTION_512x256 },
|
||||
{ 512, 384, GR_RESOLUTION_512x384 },
|
||||
{ 640, 200, GR_RESOLUTION_640x200 },
|
||||
{ 640, 350, GR_RESOLUTION_640x350 },
|
||||
{ 640, 400, GR_RESOLUTION_640x400 },
|
||||
{ 640, 480, GR_RESOLUTION_640x480 },
|
||||
{ 800, 600, GR_RESOLUTION_800x600 },
|
||||
{ 856, 480, GR_RESOLUTION_856x480 },
|
||||
{ 960, 720, GR_RESOLUTION_960x720 },
|
||||
{ 1024, 768, GR_RESOLUTION_1024x768 },
|
||||
{ 1152, 864, GR_RESOLUTION_1152x864 },
|
||||
{ 1280, 960, GR_RESOLUTION_1280x960 },
|
||||
{ 1280, 1024, GR_RESOLUTION_1280x1024 },
|
||||
{ 1600, 1024, GR_RESOLUTION_1600x1024 },
|
||||
{ 1600, 1200, GR_RESOLUTION_1600x1200 },
|
||||
{ 1792, 1344, GR_RESOLUTION_1792x1344 },
|
||||
{ 1856, 1392, GR_RESOLUTION_1856x1392 },
|
||||
{ 1920, 1440, GR_RESOLUTION_1920x1440 },
|
||||
{ 2048, 1536, GR_RESOLUTION_2048x1536 },
|
||||
{ 2048, 2048, GR_RESOLUTION_2048x2048 }
|
||||
};
|
||||
|
||||
#define NUM_RESOLUTIONS (sizeof(resolutions)/(sizeof(int)*3))
|
||||
|
@ -367,10 +386,10 @@ void VID_Init(unsigned char *palette)
|
|||
Cvar_RegisterVariable (&vid_waitforrefresh);
|
||||
Cvar_RegisterVariable (&gl_ztrick);
|
||||
|
||||
vid.maxwarpwidth = WARP_WIDTH;
|
||||
vid.maxwarpheight = WARP_HEIGHT;
|
||||
vid.colormap = host_colormap;
|
||||
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
|
||||
vid.maxwarpwidth = WARP_WIDTH;
|
||||
vid.maxwarpheight = WARP_HEIGHT;
|
||||
vid.colormap = host_colormap;
|
||||
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
|
||||
|
||||
// interpret command-line params
|
||||
|
||||
|
@ -422,8 +441,7 @@ void VID_Init(unsigned char *palette)
|
|||
vid.width = vid.conwidth;
|
||||
vid.height = vid.conheight;
|
||||
|
||||
vid.aspect = ((float)vid.height / (float)vid.width) *
|
||||
(320.0 / 240.0);
|
||||
vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
|
||||
vid.numpages = 2;
|
||||
|
||||
InitSig(); // trap evil signals
|
||||
|
@ -451,10 +469,10 @@ void VID_ExtraOptionDraw(unsigned int options_draw_cursor)
|
|||
void VID_ExtraOptionCmd(int option_cursor)
|
||||
{
|
||||
/*
|
||||
switch(option_cursor)
|
||||
{
|
||||
case 12: // Always start with 12
|
||||
break;
|
||||
}
|
||||
switch(option_cursor)
|
||||
{
|
||||
case 12: // Always start with 12
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -531,6 +531,9 @@ void Key_SetBinding (int keynum, char *binding)
|
|||
// free old bindings
|
||||
if (keybindings[keynum])
|
||||
{
|
||||
if (!Q_strncmp (keybindings[keynum], "toggleconsole", 13)) {
|
||||
consolekeys[keynum] = true;
|
||||
}
|
||||
Z_Free (keybindings[keynum]);
|
||||
keybindings[keynum] = NULL;
|
||||
}
|
||||
|
@ -541,6 +544,10 @@ void Key_SetBinding (int keynum, char *binding)
|
|||
Q_strcpy (new, binding);
|
||||
new[l] = 0;
|
||||
keybindings[keynum] = new;
|
||||
|
||||
if (!Q_strncmp (new, "toggleconsole", 13)) {
|
||||
consolekeys[keynum] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1825,8 +1825,12 @@ void PF_infokey (void)
|
|||
if (!strcmp(key, "ip"))
|
||||
value = strcpy(ov, NET_BaseAdrToString (svs.clients[e1-1].netchan.remote_address));
|
||||
else if (!strcmp(key, "ping")) {
|
||||
#ifndef QUAKEWORLD
|
||||
int ping = SV_CalcPing (&svs.clients[e1-1]);
|
||||
snprintf(ov, sizeof(ov), "%d", ping);
|
||||
#else
|
||||
snprintf(ov, sizeof(ov), "%d", svs.clients[e1-1].ping);
|
||||
#endif
|
||||
value = ov;
|
||||
} else
|
||||
value = Info_ValueForKey (svs.clients[e1-1].userinfo, key);
|
||||
|
|
|
@ -790,7 +790,7 @@ void SpectatorMove (void)
|
|||
speed = Length (pmove.velocity);
|
||||
if (speed < 1)
|
||||
{
|
||||
VectorCopy (vec3_origin, pmove.velocity)
|
||||
VectorCopy (vec3_origin, pmove.velocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define MAX_MASTERS 8 // max recipients for heartbeat packets
|
||||
|
||||
#define MAX_SIGNON_BUFFERS 8
|
||||
#define MAX_MSECS 100
|
||||
|
||||
typedef enum {
|
||||
ss_dead, // no map loaded
|
||||
|
@ -190,8 +191,10 @@ typedef struct client_s
|
|||
//===== NETWORK ============
|
||||
int chokecount;
|
||||
int delta_sequence; // -1 = no compression
|
||||
int ping;
|
||||
netchan_t netchan;
|
||||
double frame_time_1, frame_time_2;
|
||||
int msecs[MAX_MSECS], msec_count, msec_head, msec_total;
|
||||
double frame_time;
|
||||
} client_t;
|
||||
|
||||
// a client can leave the server in one of four ways:
|
||||
|
@ -236,7 +239,8 @@ typedef struct
|
|||
int serverflags; // episode completion information
|
||||
|
||||
double last_heartbeat;
|
||||
int heartbeat_sequence;
|
||||
int beatcount;
|
||||
int mheartbeat_sequence;
|
||||
svstats_t stats;
|
||||
|
||||
char info[MAX_SERVERINFO_STRING];
|
||||
|
@ -252,6 +256,10 @@ typedef struct
|
|||
|
||||
//=============================================================================
|
||||
|
||||
// HeartBeat Related things
|
||||
#define HEARTBEAT_SECONDS 3
|
||||
#define MAX_BEATCOUNT 100 // 5 Minutes
|
||||
|
||||
// edict->movetype values
|
||||
#define MOVETYPE_NONE 0 // never moves
|
||||
#define MOVETYPE_ANGLENOCLIP 1
|
||||
|
@ -378,8 +386,9 @@ void SV_SendServerinfo (client_t *client);
|
|||
void SV_ExtractFromUserinfo (client_t *cl);
|
||||
|
||||
|
||||
void Master_Heartbeat (void);
|
||||
void HeartBeat_Master (void);
|
||||
void Master_Packet (void);
|
||||
void Shutdown_Master (void);
|
||||
|
||||
//
|
||||
// sv_init.c
|
||||
|
@ -458,3 +467,6 @@ void ClientReliableWrite_Short(client_t *cl, int c);
|
|||
void ClientReliableWrite_String(client_t *cl, char *s);
|
||||
void ClientReliableWrite_SZ(client_t *cl, void *data, int len);
|
||||
|
||||
// The Heartbeat function
|
||||
|
||||
void HeartBeat (void);
|
||||
|
|
|
@ -434,7 +434,7 @@ void SV_Status_f (void)
|
|||
}
|
||||
Con_Printf ("%4i %4i %5.2f\n"
|
||||
, (int)(1000*cl->netchan.frame_rate)
|
||||
, (int)SV_CalcPing (cl)
|
||||
, cl->ping
|
||||
, 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence);
|
||||
}
|
||||
} else {
|
||||
|
@ -468,7 +468,7 @@ void SV_Status_f (void)
|
|||
}
|
||||
Con_Printf ("%4i %4i %3.1f %4i"
|
||||
, (int)(1000*cl->netchan.frame_rate)
|
||||
, (int)SV_CalcPing (cl)
|
||||
, cl->ping
|
||||
, 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence
|
||||
, cl->netchan.qport);
|
||||
if (cl->spectator)
|
||||
|
|
|
@ -36,6 +36,7 @@ netadr_t master_adr[MAX_MASTERS]; // address of group servers
|
|||
|
||||
client_t *host_client; // current client
|
||||
|
||||
cvar_t sv_maxrate = {"sv_maxrate","0"}; // server maximum rate
|
||||
cvar_t sv_mintic = {"sv_mintic","0.03"}; // bound the size of the
|
||||
cvar_t sv_maxtic = {"sv_maxtic","0.1"}; // physics time tic
|
||||
|
||||
|
@ -81,7 +82,7 @@ FILE *sv_logfile;
|
|||
FILE *sv_fraglogfile;
|
||||
|
||||
void SV_AcceptClient (netadr_t adr, int userid, char *userinfo);
|
||||
void Master_Shutdown (void);
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
@ -99,7 +100,7 @@ Quake calls this before calling Sys_Quit or Sys_Error
|
|||
*/
|
||||
void SV_Shutdown (void)
|
||||
{
|
||||
Master_Shutdown ();
|
||||
Shutdown_Master ();
|
||||
if (sv_logfile)
|
||||
{
|
||||
fclose (sv_logfile);
|
||||
|
@ -289,7 +290,7 @@ void SV_FullClientUpdate (client_t *client, sizebuf_t *buf)
|
|||
|
||||
MSG_WriteByte (buf, svc_updateping);
|
||||
MSG_WriteByte (buf, i);
|
||||
MSG_WriteShort (buf, SV_CalcPing (client));
|
||||
MSG_WriteShort (buf, client->ping);
|
||||
|
||||
MSG_WriteByte (buf, svc_updatepl);
|
||||
MSG_WriteByte (buf, i);
|
||||
|
@ -361,7 +362,7 @@ void SVC_Status (void)
|
|||
bottom = atoi(Info_ValueForKey (cl->userinfo, "bottomcolor"));
|
||||
top = (top < 0) ? 0 : ((top > 13) ? 13 : top);
|
||||
bottom = (bottom < 0) ? 0 : ((bottom > 13) ? 13 : bottom);
|
||||
ping = SV_CalcPing (cl);
|
||||
ping = cl->ping;
|
||||
Con_Printf ("%i %i %i %i \"%s\" \"%s\" %i %i\n", cl->userid,
|
||||
cl->old_frags, (int)(realtime - cl->connection_started)/60,
|
||||
ping, cl->name, Info_ValueForKey (cl->userinfo, "skin"), top, bottom);
|
||||
|
@ -711,6 +712,15 @@ void SVC_DirectConnect (void)
|
|||
else
|
||||
Con_DPrintf ("Client %s connected\n", newcl->name);
|
||||
newcl->sendinfo = true;
|
||||
|
||||
// QuakeForge stuff.
|
||||
for (i=0; i<MAX_MSECS; i++)
|
||||
newcl->msecs[i] = 0;
|
||||
|
||||
newcl->msec_count = 0;
|
||||
newcl->msec_head = 0;
|
||||
newcl->msec_total = 0;
|
||||
newcl->frame_time = realtime;
|
||||
}
|
||||
|
||||
int Rcon_Validate (void)
|
||||
|
@ -1271,8 +1281,8 @@ void SV_Frame (float time)
|
|||
// send messages back to the clients that had packets read this frame
|
||||
SV_SendClientMessages ();
|
||||
|
||||
// send a heartbeat to the master if needed
|
||||
Master_Heartbeat ();
|
||||
// Breathe in... Breathe out.. breath in...
|
||||
HeartBeat ();
|
||||
|
||||
// collect timing statistics
|
||||
end = Sys_DoubleTime ();
|
||||
|
@ -1329,6 +1339,7 @@ void SV_InitLocal (void)
|
|||
Cvar_RegisterVariable (&spawn);
|
||||
Cvar_RegisterVariable (&watervis);
|
||||
|
||||
Cvar_RegisterVariable (&sv_maxrate);
|
||||
Cvar_RegisterVariable (&developer);
|
||||
|
||||
Cvar_RegisterVariable (&timeout);
|
||||
|
@ -1387,26 +1398,69 @@ void SV_InitLocal (void)
|
|||
|
||||
//============================================================================
|
||||
|
||||
|
||||
// Lots of nifty checks done in here.. Lives by the heartbeat
|
||||
void HeartBeat_Check( void) {
|
||||
int i;
|
||||
client_t *cl;
|
||||
|
||||
|
||||
for (i=0, cl = svs.clients ; i<MAX_CLIENTS ; i++, cl++)
|
||||
{
|
||||
if (cl->state == cs_connected || cl->state == cs_spawned) {
|
||||
// Put stuff in here that you want done to every client
|
||||
|
||||
// Slades maxrate function
|
||||
if((1/cl->netchan.rate) > sv_maxrate.value && sv_maxrate.value) {
|
||||
SV_BroadcastPrintf (PRINT_HIGH, "%s was kicked for having his rate to high\n", cl->name);
|
||||
SV_ClientPrintf (cl, PRINT_HIGH, "You were kicked from the game for having a rate higher then %5.0f\n", sv_maxrate.value);
|
||||
SV_DropClient(cl);
|
||||
}
|
||||
|
||||
// Lets build our ping query tables -- Slade
|
||||
cl->ping=SV_CalcPing(cl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This is the HeartBeat of the server.. center of alot of useful stuff
|
||||
// -- Slade
|
||||
void HeartBeat (void)
|
||||
{
|
||||
|
||||
if (realtime - svs.last_heartbeat < HEARTBEAT_SECONDS)
|
||||
return; // not time to send yet
|
||||
|
||||
svs.last_heartbeat = realtime;
|
||||
if(svs.beatcount == MAX_BEATCOUNT)
|
||||
svs.beatcount = 0;
|
||||
svs.beatcount++;
|
||||
|
||||
// Do this stuff every HeartBeat
|
||||
HeartBeat_Check();
|
||||
|
||||
// Do this every 100 Beats
|
||||
if(svs.beatcount == 100) {
|
||||
HeartBeat_Master();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Master_Heartbeat
|
||||
HeartBeat_Master
|
||||
|
||||
Send a message to the master every few minutes to
|
||||
let it know we are alive, and log information
|
||||
================
|
||||
*/
|
||||
#define HEARTBEAT_SECONDS 300
|
||||
void Master_Heartbeat (void)
|
||||
void HeartBeat_Master (void)
|
||||
{
|
||||
char string[2048];
|
||||
int active;
|
||||
int i;
|
||||
|
||||
if (realtime - svs.last_heartbeat < HEARTBEAT_SECONDS)
|
||||
return; // not time to send yet
|
||||
|
||||
svs.last_heartbeat = realtime;
|
||||
|
||||
//
|
||||
// count active users
|
||||
//
|
||||
|
@ -1416,9 +1470,9 @@ void Master_Heartbeat (void)
|
|||
svs.clients[i].state == cs_spawned )
|
||||
active++;
|
||||
|
||||
svs.heartbeat_sequence++;
|
||||
svs.mheartbeat_sequence++;
|
||||
snprintf(string, sizeof(string), "%c\n%i\n%i\n", S2M_HEARTBEAT,
|
||||
svs.heartbeat_sequence, active);
|
||||
svs.mheartbeat_sequence, active);
|
||||
|
||||
|
||||
// send to group master
|
||||
|
@ -1432,12 +1486,12 @@ void Master_Heartbeat (void)
|
|||
|
||||
/*
|
||||
=================
|
||||
Master_Shutdown
|
||||
Shutdown_Master
|
||||
|
||||
Informs all masters that this server is going down
|
||||
=================
|
||||
*/
|
||||
void Master_Shutdown (void)
|
||||
void Shutdown_Master (void)
|
||||
{
|
||||
char string[2048];
|
||||
int i;
|
||||
|
|
|
@ -39,6 +39,7 @@ extern vec3_t player_mins;
|
|||
extern int fp_messages, fp_persecond, fp_secondsdead;
|
||||
extern char fp_msg[];
|
||||
extern cvar_t pausable;
|
||||
static int loss;
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
@ -854,7 +855,7 @@ void SV_Pings_f (void)
|
|||
|
||||
ClientReliableWrite_Begin (host_client, svc_updateping, 4);
|
||||
ClientReliableWrite_Byte (host_client, j);
|
||||
ClientReliableWrite_Short (host_client, SV_CalcPing(client));
|
||||
ClientReliableWrite_Short (host_client, client->ping);
|
||||
ClientReliableWrite_Begin (host_client, svc_updatepl, 4);
|
||||
ClientReliableWrite_Byte (host_client, j);
|
||||
ClientReliableWrite_Byte (host_client, client->lossage);
|
||||
|
@ -1368,31 +1369,42 @@ SV_RunCmd
|
|||
*/
|
||||
void SV_RunCmd (usercmd_t *ucmd, qboolean inside)
|
||||
{
|
||||
edict_t *ent;
|
||||
int i, n;
|
||||
int oldmsec;
|
||||
double tmp_time;
|
||||
edict_t *ent;
|
||||
int i, n, oldmsec;
|
||||
double tmp_time;
|
||||
|
||||
// To prevent a infinate loop
|
||||
if (!inside) {
|
||||
oldmsec = ucmd->msec;
|
||||
// Calculate the real msec.
|
||||
tmp_time = realtime - host_client->frame_time_2;
|
||||
tmp_time /= 2;
|
||||
// Cap it at a max of 250 msec though..
|
||||
tmp_time = realtime - host_client->frame_time;
|
||||
ucmd->msec = tmp_time * 1000;
|
||||
|
||||
if (loss)
|
||||
ucmd->msec /= (loss + 1);
|
||||
|
||||
// Cap it at a max of 250 msec though..
|
||||
ucmd->msec = min(ucmd->msec, 250);
|
||||
ucmd->msec = max(ucmd->msec, 10);
|
||||
|
||||
if (host_client->msecs[host_client->msec_head])
|
||||
host_client->msec_total-=host_client->msecs[host_client->msec_head];
|
||||
|
||||
host_client->msec_total += ucmd->msec;
|
||||
host_client->msecs[host_client->msec_head] = ucmd->msec;
|
||||
host_client->msec_head = (host_client->msec_head + 1) % 100;
|
||||
host_client->msec_count = min(100, host_client->msec_count + 1);
|
||||
|
||||
ucmd->msec = host_client->msec_total / host_client->msec_count;
|
||||
|
||||
// If were more then 10 msecs off what the client tells us, report it.
|
||||
if (abs(oldmsec - ucmd->msec) > 10) {
|
||||
printf("tmp_time: %f, realtime: %f, frame_time_1: %f\n",
|
||||
tmp_time, realtime, host_client->frame_time_1);
|
||||
printf("tmp_time: %f, realtime: %f, frame_time: %f\n",
|
||||
tmp_time, realtime, host_client->frame_time);
|
||||
printf("oldmsec: '%d', msec: '%d'\n", oldmsec,
|
||||
ucmd->msec);
|
||||
}
|
||||
host_client->frame_time_2 = host_client->frame_time_1;
|
||||
host_client->frame_time_1 = realtime;
|
||||
host_client->frame_time = realtime;
|
||||
}
|
||||
|
||||
cmd = *ucmd;
|
||||
|
@ -1660,20 +1672,19 @@ void SV_ExecuteClientMessage (client_t *cl)
|
|||
if (!sv.paused) {
|
||||
SV_PreRunCmd();
|
||||
|
||||
/*
|
||||
if (net_drop < 20)
|
||||
{
|
||||
while (net_drop > 2)
|
||||
{
|
||||
SV_RunCmd (&cl->lastcmd, 0);
|
||||
loss = net_drop;
|
||||
|
||||
if (net_drop < 20) {
|
||||
while (net_drop > 2) {
|
||||
SV_RunCmd (&cl->lastcmd, 1);
|
||||
net_drop--;
|
||||
}
|
||||
if (net_drop > 1)
|
||||
SV_RunCmd (&oldest, 0);
|
||||
SV_RunCmd (&oldest, 1);
|
||||
if (net_drop > 0)
|
||||
SV_RunCmd (&oldcmd, 0);
|
||||
SV_RunCmd (&oldcmd, 1);
|
||||
}
|
||||
*/
|
||||
|
||||
SV_RunCmd (&newcmd, 0);
|
||||
|
||||
SV_PostRunCmd();
|
||||
|
|
Loading…
Reference in a new issue