From 833249d908269d9bfc23c6c97c5ff7d648cb8e1f Mon Sep 17 00:00:00 2001 From: driAn Date: Sat, 23 Aug 2008 19:12:17 +0000 Subject: [PATCH] support for "server extensions" git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2363 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/clientgame.cpp | 18 ++++++++++++++---- source/src/protocol.cpp | 1 + source/src/protocol.h | 3 ++- source/src/protos.h | 2 +- source/src/rendergl.cpp | 4 ++-- source/src/server.cpp | 38 ++++++++++++++++++++++++++++++++++++++ source/src/weapon.cpp | 2 +- 7 files changed, 59 insertions(+), 9 deletions(-) diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 5febfa5a..04ff5dd7 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -878,7 +878,7 @@ void refreshsopmenu(void *menu, bool init) } } -playerent *findfollowplayer(int shiftdirection) +playerent *updatefollowplayer(int shiftdirection) { if(!shiftdirection) { @@ -890,6 +890,7 @@ playerent *findfollowplayer(int shiftdirection) loopv(players) if(players[i]) { if(m_teammode && !isteam(players[i]->team, player1->team)) continue; + if(players[i]->state==CS_DEAD) continue; available.add(players[i]); } if(!available.length()) return NULL; @@ -915,7 +916,7 @@ void spectate(int mode) // set new spect mode case SM_FOLLOW3RD: case SM_FOLLOW3RD_TRANSPARENT: { - if(players.length() && findfollowplayer()) break; + if(players.length() && updatefollowplayer()) break; else mode = SM_FLY; } case SM_FLY: @@ -923,7 +924,7 @@ void spectate(int mode) // set new spect mode if(player1->spectatemode != SM_FLY) { // set spectator location to last followed player - playerent *f = findfollowplayer(); + playerent *f = updatefollowplayer(); if(f) { player1->o = f->o; @@ -955,7 +956,7 @@ void togglespect() // cycle through all spectating modes void changefollowplayer(int shift) { - findfollowplayer(shift); + updatefollowplayer(shift); } COMMAND(spectate, ARG_1INT); @@ -965,3 +966,12 @@ COMMAND(changefollowplayer, ARG_1INT); int isalive() { return player1->state==CS_ALIVE ? 1 : 0; } COMMANDN(alive, isalive, ARG_NONE); +void serverextension(char *ext, char *args) +{ + if(!ext || !ext[0]) return; + size_t n = args ? strlen(args)+1 : 0; + if(n>0) addmsg(SV_EXTENSION, "rsis", ext, n, args); + else addmsg(SV_EXTENSION, "rsi", ext, n); +} + +COMMAND(serverextension, ARG_2STR); \ No newline at end of file diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index 84c48b47..a881b041 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -134,6 +134,7 @@ char msgsizesl[] = // size inclusive message token, 0 for variable SV_LISTDEMOS, 1, SV_SENDDEMOLIST, 0, SV_GETDEMO, 2, SV_SENDDEMO, 0, SV_DEMOPLAYBACK, 2, SV_CONNECT, 0, SV_CLIENT, 0, + SV_EXTENSION, 0, -1 }; diff --git a/source/src/protocol.h b/source/src/protocol.h index a0044546..26d03fe1 100644 --- a/source/src/protocol.h +++ b/source/src/protocol.h @@ -30,7 +30,8 @@ enum SV_WHOIS, SV_WHOISINFO, SV_LISTDEMOS, SV_SENDDEMOLIST, SV_GETDEMO, SV_SENDDEMO, SV_DEMOPLAYBACK, SV_CONNECT, - SV_CLIENT + SV_CLIENT, + SV_EXTENSION }; enum { SA_KICK = 0, SA_BAN, SA_REMBANS, SA_MASTERMODE, SA_AUTOTEAM, SA_FORCETEAM, SA_GIVEADMIN, SA_MAP, SA_RECORDDEMO, SA_STOPDEMO, SA_CLEARDEMOS, SA_NUM}; diff --git a/source/src/protos.h b/source/src/protos.h index c22f8b2f..e4db51a1 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -317,7 +317,7 @@ extern void refreshsopmenu(void *menu, bool init); extern char *colorname(playerent *d, int num = 0, char *name = NULL, const char *prefix = ""); extern char *colorping(int ping); extern void togglespect(); -extern playerent *findfollowplayer(int shiftdirection = 0); +extern playerent *updatefollowplayer(int shiftdirection = 0); extern void spectate(int mode); struct votedisplayinfo diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index 51a4c698..9b5d282f 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -376,7 +376,7 @@ void recomputecamera() break; case SM_FOLLOW1ST: { - playerent *f = findfollowplayer(); + playerent *f = updatefollowplayer(); if(!f) { togglespect(); return; } camera1 = f; break; @@ -384,7 +384,7 @@ void recomputecamera() case SM_FOLLOW3RD: case SM_FOLLOW3RD_TRANSPARENT: { - playerent *p = findfollowplayer(); + playerent *p = updatefollowplayer(); if(!p) { togglespect(); return; } static physent followcam; static playerent *lastplayer; diff --git a/source/src/server.cpp b/source/src/server.cpp index 2c647a8e..c2b01f78 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -1985,6 +1985,44 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1 senddemo(sender, getint(p)); break; + case SV_EXTENSION: + { + // AC server extensions + // + // rules: + // 1. extensions MUST NOT modify gameplay or the beavior of the game in any way + // 2. extensions may ONLY be used to extend or automate server administration tasks + // 3. extensions may ONLY operate on the server and must not send any additional data to the connected clients + // 4. extensions not adhering to these rules may cause the hosting server being banned from the masterserver + // + // also note that there is no guarantee that custom extensions will work in future AC versions + + + getstring(text, p, 64); + char *ext = text; // extension specifier in the form of OWNER::EXTENSION, see sample below + int n = getint(p); // legnth of data after the specifier + + // sample + if(!strcmp(ext, "driAn::writelog")) + { + // owner: driAn - root@sprintf.org + // extension: writelog - WriteLog v1.0 + // description: writes a custom string to the server log + // access: requires admin privileges + + getstring(text, p, n); + if(valid_client(sender) && clients[sender]->role==CR_ADMIN && logger) + logger->writeline(log::info, text); + } + // else if() + + // add other extensions here + + else while(n--) getint(p); // ignore unknown extensions + + break; + } + default: { int size = msgsizelookup(type); diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 60f076e4..bb290054 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -90,7 +90,7 @@ void shiftweapon(int s) selectweapon(next); } } - else if(player1->isspectating()) findfollowplayer(s); + else if(player1->isspectating()) updatefollowplayer(s); } int currentprimary() { return player1->primweap->type; }