From a7b35fe8a40b05720790d342f9397c223d8a7432 Mon Sep 17 00:00:00 2001 From: driAn Date: Mon, 28 May 2007 20:30:22 +0000 Subject: [PATCH] client roles, akimbo pickup fix git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1020 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/client.cpp | 2 +- source/src/clientgame.cpp | 37 +++++------ source/src/clients2c.cpp | 51 +++++++++----- source/src/entities.cpp | 2 +- source/src/entity.h | 6 +- source/src/main.cpp | 9 +-- source/src/protocol.cpp | 6 +- source/src/protocol.h | 6 +- source/src/protos.h | 4 +- source/src/rendergl.cpp | 1 - source/src/scoreboard.cpp | 5 +- source/src/server.cpp | 136 +++++++++++++++++++++----------------- 12 files changed, 149 insertions(+), 116 deletions(-) diff --git a/source/src/client.cpp b/source/src/client.cpp index c2fb0185..b242ecab 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -139,7 +139,7 @@ void disconnect(int onlyclean, int async) c2sinit = false; player1->clientnum = -1; player1->lifesequence = 0; - player1->ismaster = false; + player1->clientrole = CR_DEFAULT; if(m_botmode) BotManager.EndMap(); loopv(players) zapplayer(players[i]); localdisconnect(); diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 4f09dec8..06577501 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -598,32 +598,31 @@ void flagmsg(int flag, int action) // server administration -void setmaster(char *claim, char *password) +void setmaster(int claim) { - int c = atoi(claim); - if(c < 0 || c > 1) return; - - if(password[0]) - { - if(strlen(password) > 15) { conoutf("the master password has a maximum length of 15 characters"); return; } - else addmsg(SV_SETMASTERLOGIN, "ris", c, password); - } - else addmsg(SV_SETMASTER, "ri", c); + addmsg(SV_SETMASTER, "ri", claim != 0 ? 1 : 0); } -void mastercommand(int cmd, int a) // one of MCMD_* +void setadmin(char *claim, char *password) { - if(player1->ismaster) addmsg(SV_MASTERCMD, "rii", cmd, a); - else conoutf("\f3you have to be master to perform this action"); + if(!claim) return; + if(strlen(password) > 15) { conoutf("the admin password has a maximum length of 15 characters"); return; } + else addmsg(SV_SETADMIN, "ris", atoi(claim) != 0 ? 1 : 0, password); } -void kick(int player) { mastercommand(MCMD_KICK, player); } -void ban(int player) { mastercommand(MCMD_BAN, player); } -void removebans() { mastercommand(MCMD_REMBANS, 0); } -void autoteam(int enable) { mastercommand(MCMD_AUTOTEAM, enable); } -void mastermode(int mode) { mastercommand(MCMD_MASTERMODE, mode); } +void serveropcommand(int cmd, int a) // one of MCMD_* +{ + addmsg(SV_SERVOPCMD, "rii", cmd, a); +} -COMMAND(setmaster, ARG_2STR); +void kick(int player) { serveropcommand(SOPCMD_KICK, player); } +void ban(int player) { serveropcommand(SOPCMD_BAN, player); } +void removebans() { serveropcommand(SOPCMD_REMBANS, 0); } +void autoteam(int enable) { serveropcommand(SOPCMD_AUTOTEAM, enable); } +void mastermode(int mode) { serveropcommand(SOPCMD_MASTERMODE, mode); } + +COMMAND(setmaster, ARG_1INT); +COMMAND(setadmin, ARG_2STR); COMMAND(kick, ARG_1INT); COMMAND(ban, ARG_1INT); COMMAND(removebans, ARG_NONE); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 646c5413..b168adfc 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -152,9 +152,18 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) } case SV_TEXT: - if(!d) return; - getstring(text, p); - conoutf("%s:\f0 %s", d->name, text); + if(cn == -1) + { + getstring(text, p); + conoutf("MOTD:"); + conoutf("\f4%s", text); + } + else if(d) + { + getstring(text, p); + conoutf("%s:\f0 %s", d->name, text); + } + else return; break; case SV_MAPCHANGE: @@ -500,45 +509,45 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) clearbounceents(); break; - case SV_MASTERINFO: + case SV_SERVOPINFO: { - loopv(players) { if(players[i]) players[i]->ismaster = false; } - player1->ismaster = false; + loopv(players) { if(players[i]) players[i]->clientrole = CR_DEFAULT; } + player1->clientrole = CR_DEFAULT; - int m = getint(p); - if(m != -1) + int cl = getint(p), r = getint(p); + if(cl >= 0 && r >= 0) { - playerent *pl = (m == getclientnum() ? player1 : newclient(m)); + playerent *pl = (cl == getclientnum() ? player1 : newclient(cl)); if(pl) { - pl->ismaster = true; - conoutf("%s claimed master status", pl == player1 ? "you" : pl->name); + pl->clientrole = r; + conoutf("%s claimed %s status", pl == player1 ? "you" : pl->name, r == CR_ADMIN ? "admin" : "master"); } } break; } - case SV_MASTERCMD: + case SV_SERVOPCMD: { int cmd = getint(p), arg = getint(p); switch(cmd) { - case MCMD_KICK: - case MCMD_BAN: + case SOPCMD_KICK: + case SOPCMD_BAN: { playerent *pl = (arg == getclientnum() ? NULL : getclient(arg)); - if(pl) conoutf("%s has been %s", pl->name, cmd == MCMD_KICK ? "kicked" : "banned"); + if(pl) conoutf("%s has been %s", pl->name, cmd == SOPCMD_KICK ? "kicked" : "banned"); break; } - case MCMD_REMBANS: + case SOPCMD_REMBANS: conoutf("bans removed"); break; - case MCMD_MASTERMODE: + case SOPCMD_MASTERMODE: conoutf("mastermode set to \"%s\"", arg ? "private" : "open"); break; - case MCMD_AUTOTEAM: + case SOPCMD_AUTOTEAM: autoteambalance = arg == 1; if(!joining) conoutf("autoteam is %s", autoteambalance ? "enabled" : "disabled"); break; @@ -546,6 +555,12 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) break; } + case SV_SERVOPCMDDENIED: + { + conoutf("\f3denied. you have to be at least %s to perform this action", getint(p) == CR_ADMIN ? "admin" : "master"); + break; + } + case SV_FORCETEAM: { changeteam(getint(p)); diff --git a/source/src/entities.cpp b/source/src/entities.cpp index f4146711..548a1a5c 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -117,7 +117,7 @@ void realpickup(int n, playerent *d) d->akimbomillis = lastmillis+30000; d->mag[GUN_PISTOL] = 16; equipitem(d, n, d->ammo[1], 9); - if(d==player1) weaponswitch(GUN_PISTOL); + if(d==player1 && d->gunselect!=GUN_SNIPER) weaponswitch(GUN_PISTOL); break; } } diff --git a/source/src/entity.h b/source/src/entity.h index 1ed0e18a..6bb77a04 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -43,8 +43,8 @@ struct itemstat { int add, start, max, sound; }; // End add enum { ENT_PLAYER = 0, ENT_BOT, ENT_CAMERA, ENT_BOUNCE }; - enum { CS_ALIVE = 0, CS_DEAD, CS_LAGGED, CS_EDITING }; +enum { CR_DEFAULT, CR_MASTER, CR_ADMIN }; struct physent { @@ -150,7 +150,7 @@ struct playerent : dynent int health, armour; int gunselect, gunwait; int lastaction, lastattackgun, lastmove, lastpain, lastteamkill; - bool ismaster; + int clientrole; bool attacking; int ammo[NUMGUNS]; int mag[NUMGUNS]; @@ -170,7 +170,7 @@ struct playerent : dynent poshist history; // Previous stored locations of this player - playerent() : clientnum(-1), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), lastpain(0), lastteamkill(0), ismaster(false), + playerent() : clientnum(-1), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), lastpain(0), lastteamkill(0), clientrole(CR_DEFAULT), shots(0), reloading(false), primary(GUN_ASSAULT), nextprimary(GUN_ASSAULT), skin(0), nextskin(0), inhandnade(NULL) { diff --git a/source/src/main.cpp b/source/src/main.cpp index 06466ab0..1af9e5be 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -162,7 +162,7 @@ int main(int argc, char **argv) { bool dedicated = false; int fs = SDL_FULLSCREEN, depth = 0, bpp = 0, fsaa = 0, par = 0, uprate = 0, maxcl = DEFAULTCLIENTS; - char *sdesc = "", *ip = "", *master = NULL, *passwd = "", *maprot = NULL, *masterpwd = NULL; + char *sdesc = "", *ip = "", *master = NULL, *passwd = "", *maprot = NULL, *adminpwd = NULL, *srvmsg = NULL; #define initlog(s) puts("init: " s) initlog("sdl"); @@ -185,8 +185,9 @@ int main(int argc, char **argv) case 'm': master = a; break; case 'p': passwd = a; break; case 'r': maprot = a; break; - case 'x' : masterpwd = a; break; // EDIT: AH - case 'c': maxcl = atoi(a); break; //EDIT: AH + case 'x' : adminpwd = a; break; + case 'c': maxcl = atoi(a); break; + case 'o': srvmsg = a; break; default: conoutf("unknown commandline option"); } else conoutf("unknown commandline argument"); @@ -203,7 +204,7 @@ int main(int argc, char **argv) if(enet_initialize()<0) fatal("Unable to initialise network module"); initclient(); - initserver(dedicated, uprate, sdesc, ip, master, passwd, maxcl, maprot, masterpwd); // never returns if dedicated + initserver(dedicated, uprate, sdesc, ip, master, passwd, maxcl, maprot, adminpwd, srvmsg); // never returns if dedicated initlog("world"); empty_world(7, true); diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index 6f4aadee..cbd27cd9 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -88,14 +88,14 @@ char msgsizesl[] = // size inclusive message token, 0 for variable SV_INITS2C, 5, SV_INITC2S, 0, SV_POS, 0, SV_TEXT, 0, SV_TEAMTEXT, 0, SV_SOUND, 2, SV_CDIS, 2, SV_GIBDIED, 2, SV_DIED, 2, SV_GIBDAMAGE, 4, SV_DAMAGE, 4, SV_SHOT, 9, SV_FRAGS, 2, SV_RESUME, 3, SV_TIMEUP, 2, SV_EDITENT, 10, SV_MAPRELOAD, 2, SV_ITEMACC, 2, - SV_MAPCHANGE, 0, SV_ITEMSPAWN, 2, SV_ITEMPICKUP, 3, SV_DENIED, 2, + SV_MAPCHANGE, 0, SV_ITEMSPAWN, 2, SV_ITEMPICKUP, 3, SV_PING, 2, SV_PONG, 2, SV_CLIENTPING, 2, SV_GAMEMODE, 2, SV_EDITH, 7, SV_EDITT, 7, SV_EDITS, 6, SV_EDITD, 6, SV_EDITE, 6, SV_SENDMAP, 0, SV_RECVMAP, 1, SV_SERVMSG, 0, SV_ITEMLIST, 0, SV_WEAPCHANGE, 2, SV_MODELSKIN, 2, - SV_FLAGPICKUP, 2, SV_FLAGDROP, 2, SV_FLAGRETURN, 2, SV_FLAGSCORE, 2, SV_FLAGRESET, 2, SV_FLAGINFO, 0, SV_FLAGS, 2, // EDIT: AH + SV_FLAGPICKUP, 2, SV_FLAGDROP, 2, SV_FLAGRETURN, 2, SV_FLAGSCORE, 2, SV_FLAGRESET, 2, SV_FLAGINFO, 0, SV_FLAGS, 2, SV_ARENASPAWN, 0, SV_ARENAWIN, 0, - SV_SETMASTER, 2, SV_SETMASTERLOGIN, 0, SV_MASTERINFO, 2, SV_MASTERCMD, 3, + SV_SETMASTER, 2, SV_SETADMIN, 0, SV_SERVOPINFO, 3, SV_SERVOPCMD, 3, SV_SERVOPCMDDENIED, 2, SV_FORCETEAM, 2, SV_AUTOTEAM, 2, SV_PWD, 0, SV_CLIENT, 0, diff --git a/source/src/protocol.h b/source/src/protocol.h index 2fa15f01..da9b9da2 100644 --- a/source/src/protocol.h +++ b/source/src/protocol.h @@ -12,20 +12,20 @@ enum SV_INITS2C = 0, SV_INITC2S, SV_POS, SV_TEXT, SV_TEAMTEXT, SV_SOUND, SV_CDIS, SV_GIBDIED, SV_DIED, SV_GIBDAMAGE, SV_DAMAGE, SV_SHOT, SV_FRAGS, SV_RESUME, SV_TIMEUP, SV_EDITENT, SV_MAPRELOAD, SV_ITEMACC, - SV_MAPCHANGE, SV_ITEMSPAWN, SV_ITEMPICKUP, SV_DENIED, + SV_MAPCHANGE, SV_ITEMSPAWN, SV_ITEMPICKUP, SV_PING, SV_PONG, SV_CLIENTPING, SV_GAMEMODE, SV_EDITH, SV_EDITT, SV_EDITS, SV_EDITD, SV_EDITE, SV_SENDMAP, SV_RECVMAP, SV_SERVMSG, SV_ITEMLIST, SV_WEAPCHANGE, SV_MODELSKIN, SV_FLAGPICKUP, SV_FLAGDROP, SV_FLAGRETURN, SV_FLAGSCORE, SV_FLAGRESET, SV_FLAGINFO, SV_FLAGS, //EDIT: AH SV_ARENASPAWN, SV_ARENAWIN, - SV_SETMASTER, SV_SETMASTERLOGIN, SV_MASTERINFO, SV_MASTERCMD, + SV_SETMASTER, SV_SETADMIN, SV_SERVOPINFO, SV_SERVOPCMD, SV_SERVOPCMDDENIED, SV_FORCETEAM, SV_AUTOTEAM, SV_PWD, SV_CLIENT, }; -enum { MCMD_KICK = 0, MCMD_BAN, MCMD_REMBANS, MCMD_MASTERMODE, MCMD_AUTOTEAM }; +enum { SOPCMD_KICK = 0, SOPCMD_BAN, SOPCMD_REMBANS, SOPCMD_MASTERMODE, SOPCMD_AUTOTEAM, SOPCMD_MOTD, SOPCMD_NUM}; #define DMF 16.0f #define DAF 1.0f diff --git a/source/src/protos.h b/source/src/protos.h index d40fcda4..c7fe5529 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -144,7 +144,7 @@ extern void flaginbase(int flag, int action, int act); extern void flagmsg(int flag, int action); extern void arenarespawn(); extern void respawn(); -extern void mastercommand(int cmd, int arg1); +extern void serveropcommand(int cmd, int arg1); extern void refreshmastermenu(void *menu, bool init); // scoreboard @@ -277,7 +277,7 @@ extern char *hudgunnames[]; extern void renderhudgun(); // server -extern void initserver(bool dedicated, int uprate, char *sdesc, char *ip, char *master, char *passwd, int maxcl, char *maprot, char *masterpwd); // EDIT: AH +extern void initserver(bool dedicated, int uprate, char *sdesc, char *ip, char *master, char *passwd, int maxcl, char *maprot, char *adminpwd, char *srvmsg); extern void cleanupserver(); extern void localconnect(); extern void localdisconnect(); diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index e0300e85..24700bda 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -444,7 +444,6 @@ void clearminimap() } COMMAND(clearminimap, ARG_NONE); - VARFP(minimapres, 7, 9, 10, clearminimap()); void drawminimap(int w, int h) diff --git a/source/src/scoreboard.cpp b/source/src/scoreboard.cpp index ae323146..8d7858ea 100644 --- a/source/src/scoreboard.cpp +++ b/source/src/scoreboard.cpp @@ -17,8 +17,9 @@ vector scorelines; void renderscore(void *menu, playerent *d, int cn) { const char *status = ""; - if(d->ismaster) status = "\f0"; - if(d->state==CS_DEAD) status = "\f4"; + if(d->clientrole==CR_MASTER) status = "\f0"; + else if(d->clientrole==CR_ADMIN) status = "\f3"; + else if(d->state==CS_DEAD) status = "\f4"; s_sprintfd(lag)("%d", d->plag); string &s = scorelines.add().s; if(m_ctf) s_sprintf(s)("%d\t%d\t%s\t%d\t%s\t%s%s\t%d", d->flagscore, d->frags, d->state==CS_LAGGED ? "LAG" : lag, d->ping, d->team, status, d->name, cn); diff --git a/source/src/server.cpp b/source/src/server.cpp index 0a38766b..19f41a8c 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -41,7 +41,7 @@ struct client // server side version of "dynent" type uint pos[3]; clientscore score; bool arenadeath; - bool ismaster; + int role; bool isauthed; // for passworded servers vector position, messages; @@ -52,8 +52,9 @@ struct client // server side version of "dynent" type arenadeath = true; position.setsizenodelete(0); messages.setsizenodelete(0); - ismaster = isauthed = false; - } + isauthed = false; + role = CR_DEFAULT; + } }; vector clients; @@ -183,7 +184,7 @@ bool buildworldstate() int maxclients = DEFAULTCLIENTS; string smapname; -char *masterpasswd = NULL; +char *adminpasswd = NULL, *motd = NULL; int numclients() { @@ -196,7 +197,8 @@ void zapclient(int c) { if(!clients.inrange(c)) return; clients[c]->type = ST_EMPTY; - clients[c]->ismaster = clients[c]->isauthed = false; + clients[c]->isauthed = false; + clients[c]->role = CR_DEFAULT; } int freeteam() @@ -587,7 +589,7 @@ bool vote(char *map, int reqmode, int sender) { if(!valid_client(sender)) return false; - if(configsets.length() && curcfgset < configsets.length() && !configsets[curcfgset].vote && !clients[sender]->ismaster) + if(configsets.length() && curcfgset < configsets.length() && !configsets[curcfgset].vote && clients[sender]->role == CR_DEFAULT) { s_sprintfd(msg)("%s voted, but voting is currently disabled", clients[sender]->name); sendservmsg(msg); @@ -605,7 +607,7 @@ bool vote(char *map, int reqmode, int sender) if(yes==1 && no==0) return true; // single player s_sprintfd(msg)("%s suggests mode \"%s\" on map %s (set map to vote)", clients[sender]->name, modestr(reqmode), map); sendservmsg(msg); - if(yes/(float)(yes+no) <= 0.5f && !clients[sender]->ismaster) return false; + if(yes/(float)(yes+no) <= 0.5f && clients[sender]->role == CR_DEFAULT) return false; sendservmsg("vote passed"); resetvotes(); return true; @@ -632,72 +634,81 @@ bool isbanned(int cn) return false; } -int master() +int serveroperator() { - loopv(clients) if(clients[i]->type!=ST_EMPTY && clients[i]->ismaster) return i; + loopv(clients) if(clients[i]->type!=ST_EMPTY && clients[i]->role > CR_DEFAULT) return i; return -1; } -void sendmasterinfo(int receiver) +void sendserveropinfo(int receiver) { - sendf(receiver, 1, "rii", SV_MASTERINFO, master()); + int op = serveroperator(); + sendf(receiver, 1, "riii", SV_SERVOPINFO, op, op >= 0 ? clients[op]->role : -1); } -void setmaster(int client, bool claim, char *pwd = NULL) -{ - if(!isdedicated || !valid_client(client)) return; - - int curmaster = master(); - if((curmaster == -1 || curmaster == client) || (pwd && pwd[0] && masterpasswd && !strcmp(masterpasswd, pwd))) - { - loopv(clients) if(clients[i]->type!=ST_EMPTY) clients[i]->ismaster = false; - clients[client]->ismaster = claim; - sendmasterinfo(-1); - } - else if(pwd && pwd[0]) - { - disconnect_client(client, DISC_MLOGINFAIL); // avoid brute-force - } +void changeclientrole(int client, int role, char *pwd = NULL) +{ + if(!isdedicated || !valid_client(client)) return; + int serverop = serveroperator(); + if(role == CR_DEFAULT || (role == CR_MASTER && serverop < 0) || (role == CR_ADMIN && pwd && pwd[0] && adminpasswd && !strcmp(adminpasswd, pwd))) + { + if(role > CR_DEFAULT) loopv(clients) clients[i]->role = CR_DEFAULT; + clients[client]->role = role; + sendserveropinfo(-1); + } + else if(pwd && pwd[0]) disconnect_client(client, DISC_MLOGINFAIL); // avoid brute-force } -void mastercmd(int sender, int cmd, int a) +void serveropcmddenied(int receiver, int requiredrole) { - if(!isdedicated || clients[sender]->ismaster==false) return; + sendf(receiver, 1, "rii", SV_SERVOPCMDDENIED, requiredrole); +} + +void serveropcmd(int sender, int cmd, int a) +{ + if(!isdedicated || !valid_client(sender) || cmd < 0 || cmd >= SOPCMD_NUM) return; + #define requirerole(r) if(clients[sender]->role < r) { sendf(sender, 1, "rii", SV_SERVOPCMDDENIED, r); return; } + switch(cmd) { - case MCMD_KICK: + case SOPCMD_KICK: { - if(!valid_client(a)) return; + requirerole(CR_MASTER); + if(!valid_client(a)) return; disconnect_client(a, DISC_MKICK); break; } - case MCMD_BAN: + case SOPCMD_MASTERMODE: { + requirerole(CR_MASTER); + if(a < 0 || a >= MM_NUM) return; + mastermode = a; + break; + } + case SOPCMD_AUTOTEAM: + { + requirerole(CR_MASTER); + if(a < 0 || a > 1) return; + if((autoteam = a == 1) == true && m_teammode) shuffleteams(); + break; + } + case SOPCMD_BAN: + { + requirerole(CR_ADMIN); if(!valid_client(a)) return; ban b = { clients[a]->peer->address, lastsec+20*60 }; bans.add(b); disconnect_client(a, DISC_MBAN); break; } - case MCMD_REMBANS: + case SOPCMD_REMBANS: { + requirerole(CR_ADMIN); if(bans.length()) bans.setsize(0); break; } - case MCMD_MASTERMODE: - { - if(a < 0 || a >= MM_NUM) return; - mastermode = a; - break; - } - case MCMD_AUTOTEAM: - { - if(a < 0 || a > 1) return; - if((autoteam = a == 1) == true && m_teammode) shuffleteams(); - break; - } } - sendf(-1, 1, "riii", SV_MASTERCMD, cmd, a); + sendf(-1, 1, "riii", SV_SERVOPCMD, cmd, a); } // sending of maps between clients @@ -901,23 +912,23 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1 case SV_SETMASTER: { - setmaster(sender, getint(p) != 0); + changeclientrole(sender, getint(p) != 0 ? CR_MASTER : CR_DEFAULT, NULL); break; } - case SV_SETMASTERLOGIN: + case SV_SETADMIN: { bool claim = getint(p) != 0; getstring(text, p); - setmaster(sender, claim, text); + changeclientrole(sender, claim ? CR_ADMIN : CR_DEFAULT, text); break; } - case SV_MASTERCMD: + case SV_SERVOPCMD: { int cmd = getint(p); int arg = getint(p); - mastercmd(sender, cmd, arg); + serveropcmd(sender, cmd, arg); break; } @@ -974,7 +985,7 @@ void send_welcome(int n) putint(p, -1); } } - if(clients[n]->type == ST_TCPIP && master() != -1) sendmasterinfo(n); + if(clients[n]->type == ST_TCPIP && serveroperator() != -1) sendserveropinfo(n); loopv(clients) { client &c = *clients[i]; @@ -990,9 +1001,14 @@ void send_welcome(int n) putint(p, SV_FORCETEAM); putint(p, freeteam()); } - putint(p, SV_MASTERCMD); - putint(p, MCMD_AUTOTEAM); + putint(p, SV_SERVOPCMD); + putint(p, SOPCMD_AUTOTEAM); putint(p, autoteam); + if(motd) + { + putint(p, SV_TEXT); + sendstring(motd, p); + } enet_packet_resize(packet, p.length()); sendpacket(n, 1, packet); if(smapname[0] && m_ctf) loopi(2) sendflaginfo(i, -1, n); @@ -1177,7 +1193,7 @@ void localconnect() send_welcome(c.clientnum); } -void initserver(bool dedicated, int uprate, char *sdesc, char *ip, char *master, char *passwd, int maxcl, char *maprot, char *masterpwd) // EDIT: AH +void initserver(bool dedicated, int uprate, char *sdesc, char *ip, char *master, char *passwd, int maxcl, char *maprot, char *adminpwd, char *srvmsg) { if(passwd) s_strcpy(serverpassword, passwd); maxclients = maxcl > 0 ? min(maxcl, MAXCLIENTS) : DEFAULTCLIENTS; @@ -1192,7 +1208,8 @@ void initserver(bool dedicated, int uprate, char *sdesc, char *ip, char *master, loopi(maxclients) serverhost->peers[i].data = (void *)-1; if(!maprot || !maprot[0]) maprot = newstring("config/maprot.cfg"); readscfg(path(maprot)); - if(masterpwd && masterpwd[0]) masterpasswd = masterpwd; + if(adminpwd && adminpwd[0]) adminpasswd = adminpwd; + if(srvmsg && srvmsg[0]) motd = srvmsg; } resetserverifempty(); @@ -1214,10 +1231,10 @@ void initserver(bool dedicated, int uprate, char *sdesc, char *ip, char *master, void localservertoclient(int chan, uchar *buf, int len) {} void fatal(char *s, char *o) { cleanupserver(); printf("fatal: %s\n", s); exit(EXIT_FAILURE); } -int main(int argc, char **argv) // EDIT: AH +int main(int argc, char **argv) { int uprate = 0, maxcl = DEFAULTCLIENTS; - char *sdesc = "", *ip = "", *master = NULL, *passwd = "", *maprot = "", *masterpwd = NULL; + char *sdesc = "", *ip = "", *master = NULL, *passwd = "", *maprot = "", *adminpasswd = NULL, *srvmsg = NULL; for(int i = 1; i