melidas Posted March 18, 2008 Report Share Posted March 18, 2008 Sveiki, Nu man ir divi serveri, bet es velos dabut plugin, lai ieejot piemeram kz serveri uzrakstitu komandu /server un man paradiitos mans pub serveris ! un es 4ipa varetu uzreiz konnect pie vinja... ! esmu spelejis dazos serv kur tads plugin ir, bet shodien visu dienu mekleju nevareju atrast! moz kads paliidzes iedos link... Link to comment Share on other sites More sharing options...
Kiwix Posted March 18, 2008 Report Share Posted March 18, 2008 Ned!rs.. Visa diena Tev skaitās 30 sekundes, lai uzrakstītu šo debīlo postu... Link to comment Share on other sites More sharing options...
GOMA smile Posted March 18, 2008 Report Share Posted March 18, 2008 es centos bet man visu laiku gluki bija , kautkas negaja utt Link to comment Share on other sites More sharing options...
Ritsuki Posted March 19, 2008 Report Share Posted March 19, 2008 man ar vinu gluki Link to comment Share on other sites More sharing options...
DeimoN Posted March 19, 2008 Report Share Posted March 19, 2008 nu pluginu jums iedeva, nu un, ka nemaakat uzstaadiit? Link to comment Share on other sites More sharing options...
GOMA smile Posted March 19, 2008 Report Share Posted March 19, 2008 mak tikai kadu laicinu japa4akarejas un tad viss aizies Link to comment Share on other sites More sharing options...
harison555 Posted March 19, 2008 Report Share Posted March 19, 2008 /* Server redirect plugin - ? 2006 x0R ([email protected]) - www.n-ice.org License: ЇЇЇЇЇЇЇЇ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA In addition, as a special exception, the author gives permission to link the code of this program with the Half-Life Game Engine ("HL Engine") and Modified Game Libraries ("MODs") developed by Valve, L.L.C ("Valve"). You must obey the GNU General Public License in all respects for all of the code used other than the HL Engine and MODs from Valve. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. Description/Features: ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ First of all, if you are too lazy to read all this don't bother me with problems or questions! The plugin does several things that all can be turned on or off seperately by CVAR's: - on startup it reads the available servers from SERVERFILE ("amxmodx/config/serverlist.ini" by default), see next section for an example - the servers must be in the format "address:port=name" each on a line by itself where address can be an IP or DNS name - if you use DNS names look at the CVAR redirect_external_address as well - saying /server shows a list of available servers (if redirect_manual is 1) - people can choose a number from the list and are immediately sent to that server - when the server is full (one free slot left, that is) people are automatically forwarded to a random server from the list - redirect_auto enables or disables this - when a server from the list is full or down the server is disabled in the menu and players are not redirected there automatically - to be able to check whether a server is down redirect_check_method must be > 0 and to check whether it is full redirect_check_method must be > 1 - the servers are announced every redirect_announce seconds - set to 0 to turn announcements off; the server list is shown as HUD message and for living players displayed at the top and for dead players displayed somewhere below the top so it is not covered by the "spectator bars"; how much information the announcements include depends on redirect_check_method - depending on redirect_check_method servers can be checked for being down/full or even current map, number of current players and maximum players can be displayed in the menu and in the announcements - when no server is available for automatic redirection the player is just dropped with an appropriate message - when someone is redirected either manually or automatically this is shown to the other players telling who was redirected and to which server - it is also announced that people can say /follow to follow this player to the server and they are redirected as well - both the announcements and the follow feature can be enabled or disabled by CVAR (redirect_follow) - the plugin is language aware (thus you need to place the redirect.txt in amxmodx/data/lang/) - the server can show whether someone that just connects was redirected to the server and from what server he is coming from - the own IP address is detected automatically and disabled in the server list - automatic detection does not work if you use DNS names in the SERVERFILE - in this case set the DNS address of the own server in redirect_external_address for the detection to work - detecting the own server is NECESSARY for the plugin to work correctly - with CVAR redirect_retry set to 1 the server can put people into a retry queue to be redirected back to the last server (e.g. when they were automatically redirected but only want to play on the server they connected to) Server List File: ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ The file is in ini format. The section name is the server name. The following keys are recognized: - address = server address (can be IP or DNS name) - port = server port - a value between 1025 and 65536, default 27015 - cmdbackup = defines how often the UDP request is resent to the server (with redirect_check_method > 0), default 2 - noauto = overrides the redirect_auto setting for this server, default is redirect_auto - nomanual = overrides the redirect_manual setting for this server, default is redirect_manaul - nodisplay = if this is set to 1 it will hide the server from the /server list and announcements, default 0 - adminslots = if this is set to 1 the plugin will redirect only people with reserved slot there if it's e.g. 12/13 players on the target server, default 0 - password = the password that is needed to connect to the server, default <none> - publicpassword = if set to 1, all players can connect to passworded servers, when set to 0 only admins, default 0 If a value is not specified the default value is used. The "address" key always must be specified and doesn't have a default value Here is an example how the server file could look like: /ЇЇЇЇЇЇЇЇЇЇ serverlist.ini ЇЇЇЇЇЇЇЇЇЇЇЇ\ [my example server] address=example.n-ice.org port=27015 cmdbackup=5 noauto=1 nomanual=0 nodisplay=0 [my 2nd example server] address=example2.n-ice.org port=27015 \______________________________________/ I recommend that all servers have the same SERVERFILE. This is not necessary with redirect_show 0 but it's still better, because it could confuse users when not all servers are in the same place in the menu on every server. Please be aware that when using more than 5 servers in SERVERFILE you have to change the define MAX_SERVERFORWARDS and recompile the plugin. If there are more servers in the file than specified by MAX_SERVERFORWARDS the other servers will be ignored. Available CVAR's: ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ redirect_active - 1/0 activate/deactivate redirect plugin - when this is set to 0 all other CVAR's are ignored, default 0 redirect_auto - 0 = disable automatic redirecting when server is full/down, 1 = redirect to random server from list, 2 = redirect to next server in list, default 0 redirect_manual - 1/0 enable/disable manual redirecting with /server, default 0 redirect_follow - 1/0 enable/disable following players with /follow to a server they were redirected to - people can still use /server to follow a player though, default 0 redirect_external_address - own external server address - only needed when you use DNS names instead of IPs in SERVERFILE - this must match the name in SERVERFILE - include the port! redirect_check_method - check the servers in the list - 0 = no checks, 1 = ping only(to check whether a server is down), 2 = check active players and max. players as well, default 0 redirect_announce - announce server list with stats (depends on redirect_check_method) in center every redirect_announce seconds - set to 0 for off, default 60 redirect_announce_mode - control who announcements are displayed for: 1 = alive players , 2 = dead players, 3 = both redirect_announce_alivepos_x - the vertical position of the announcements displayed to living people, default -1.0 redirect_announce_alivepos_y - the horizontal position of the announcements displayed to living people, default 0.01 redirect_announce_deadpos_x - the vertical position of the announcements displayed to living people, default -1.0 redirect_announce_deadpos_y - the horizontal position of the announcements displayed to living people, default 0.35 redirect_show - 1/0 enable/disable redirection information in chat area, default 1 redirect_adminslots - 1/0 enable/disable adminslots - when set to 1 people are redirected off the server when someone with a reserved slot connects, default 0 redirect_retry - 1/0 enable/disable retry queue feature - when set to 1 players can say /retry and are redirected as soon as a slot on the target server is free (currently only works for redirecting them back to the server that redirected them to the current server), default 0 Advanced users should also check out the defines for more options, especially QUERY_INTERVAL could be interesting. Min. Requirements: ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ - Metamod v1.18 - HLDS v3.1.1.1 - AMXX v1.70 Modules: ЇЇЇЇЇЇЇЇЇ The plugin requires the modules engine and sockets to be loaded. You can enable them in your modules.ini. If you don't want to load the sockets module search for the line containing require_module("sockets") and comment it out or delete it. When doing this you can only use redirect_check_method 0. If you set this to something different your server might crash or other problems arise. Known issues: ЇЇЇЇЇЇЇЇЇЇЇЇЇ #1 some people report crashes with CS 1.6 and redirect_check_method 1/2 if the server being checked is on the same IP (only different port) so set to 0 if your server hangs after some time #2 as the length of menu items is limited don't specify too long server names - if an item is too long it is just truncated Changelog: ЇЇЇЇЇЇЇЇЇЇ Note: The first version that was released to the public was v0.3. v0.1 and v0.2 were only running on my servers for some time before I started the next version. v0.1: - reads the available servers from a config file - people can show a server menu by saying /server - automatic server forwarding to the next server in the list when server is full - announcing of redirection for other players on the server - people can say /follow to follow the last forwarded player - when redirect_external_address is set the own address is automatically detected v0.2: - external address is automatically detected without having redirect_external_address set, for DNS names redirect_external_address is still needed to be set though - introduced CVAR redirect_check_method where 0 = disabled 1 = the servers in the list are pinged every QUERY_INTERVAL seconds to check whether they are online 2 = the servers in the list are queried for actual and maximum players and map every QUERY_INTERVAL seconds - depending on redirect_check_method the menu displays: 0 = own server as disabled, others as available in format: server name (server address) 1 = own server as disabled, others as available in format "server name (server address)" or down in format "server name (server address) (down)" 2 = own server as disabled, others as available in format "server name [current map] (active players/max. players)" or down in format "server name (server address) (down)" - servers that are down are displayed as down in the list and people cannot have themselves redirected there (disabled in menu) - random automatic forward instead of choosing the next free server from the list - the server doesn't forward to servers considered being down when server is full - if no server is available (due to being down) players are not redirected and have a message displayed that they couldn't be forwarded v0.3 - for redirect_check_method 2: - no automatic redirection to full servers anymore (active players = maximum players) - full servers are displayed in the menu with red brackets surrounding the player numbers and can't be selected - the plugin is now language system aware - introduced CVAR redirect_send_tag where 0 = disabled 1 = when redirecting it prepends [R<server number>] to people's names with <server number> being the own server number in SERVERFILE indicating to the receive server that this player was redirected from this server - introduced CVAR redirect_receive_tag where 0 = disabled 1 = when someone connects with prepended [R<server number>] to his name the server will show a message that the player was redirected from that server and remove the tag from the name - introduced CVAR redirect_announce: The value of this CVAR can be 0 for turning announcements of. If set to a higher floating point value this is the time in seconds how often the announcements are shown. - made status detection more stable by sending more UDP packets - made status detection more stable through a completely new code for receive handling - several small optimizations and bug fixes here and there I don't recall in detail v0.4 - modified default messages for connect and team joining so that they display player names without redirect tags if redirect_receive_tag = 1 - modified the name change code to be more reliable - HL1 steam server status querying is now working - this should make status information work for all HL1 mods running on Steam - plugin now uses the much faster cvar querying introduced with AMXX 1.70 - load routine now checks whether there are more servers in the file than can be loaded v0.4.1 - name changes from tagged names are now hidden as well - this means with redirect_receive_tag = 1 the complete procedure of tagging is hidden v0.4.7 - fixed a bug where automatic redirection didn't work with redirect_check_method 0 - fixed a bug where the PLUGIN_TAG was missing in the message MSG_NO_REDIRECT_SERVER - fixed many messages that were still displayed with server's default language - fixed code to display announcement in different height for dead and alive players - introduced CVAR redirect_announce_mode where 1 = announcements while playing 2 = announcements while dead/spectator 3 = both default is 3 - only effective when redirect_announce > 0[xOR] v0.4.8 - added code to require_module sockets - introduced cvar redirect_version for external version check v0.5.0 - fixed an error that crashed the server when redirecting automatically v0.6.0 - sorted out several unused variables - redirect_auto 2 redirects to next server in list (1 = random server, like before) - added new format for SERVERFILE - it is now an ini file - server status (or ping) request should be more stable due to added cmdbackup of 2 (2 additional request packets are sent) - the default cmdbackup value can be overridden in SERVERFILE for each server - redirect_manual can be overriden in SERVERFILE for each server - redirect_auto can be overriden in SERVERFILE for each server - servers in the list can be hidden (from list + announcements) with a key in SERVERFILE - added server command redirect_reload which will make the plugin reload the SERVERFILE v0.6.3 - changed UDP timeout value to default with hope to fix crash problem with redirect_check_method > 0 - sockets are now initialized to 0 after freeing them - fixed a bug where second server was displayed as being down - fixed a bug where for first server the map of the second server was displayed - changed default QUERY_INTERVAL to 20 - changed UDP receive code to be faster and handle responses more secure and reliable v0.7.0 - UDP timeout value change didn't help and was changed back to 1 - fixed the "unknown command: pickserver" message when using pickserver command - removed nick tagging - server now displays where someone was redirected from without nick tagging - removed text message hooks as they are not needed anymore - removed CVAR redirect_send_tag - removed CVAR redirect_receive_tag - servers are not redirecting back to source servers anymore, thus preventing an endless loop - fixed a bug where redirect_auto 2 wouldn't choose the next but the first server in list - introduced CVAR redirect_show where 0 = disabled 1 = show redirection information in chat area when someone was redirected (default) v0.7.5 - removed support for AMXX versions older than 1.70 to cleanup code - added command redirect_announce_now which will immediately display server announcement to all players - introduced CVAR redirect_announce_alivepos_x - introduced CVAR redirect_announce_alivepos_y - introduced CVAR redirect_announce_deadpos_x - introduced CVAR redirect_announce_deadpos_y - menues now don't have colors anymore when the mod does not support coloured menues - added command redirect_user which can redirect a user - added native redirect(id, nServer) which can be called by other plugins - sentence "say /server..." is no longer displayed in announcement if redirect_manual is set to 0 v0.8.0 - introduced CVAR redirect_adminslots - plugin will now redirect another user to free up a slot when someone with a reserved slot connects - improved detection for coloured menues - servers in server list can have a new setting "adminslots" to tell whether they have adminslots - plugin will not allow to redirect manually anymore when there is only one free slot left on the target server, except when the target server has an admin slot and the player to be redirected has reservation flag - native redirect function got a new parameter to tell whether people are dropped when no valid target server is found v0.8.2 - setting redirect_announce to 0 will now stop the announcements from being displayed immediately - fixed a bug where announcements were displayed although redirect_announce is set to 0 - plugin will not allow to redirect manually anymore when there is only one free slot left on the target server, except when the target server has an admin slot and the player to be redirected has reservation flag [should work now] v0.8.4 - introduced CVAR redirect_maxadmins - with this the maximum number of admins can be limited - if the maximum number of connected admins is reached the plugin acts like there were no admin slots - fixed a bug where server parameters in server list beginning with "no" were always interpreted as "1" v0.9.0 - added functionality for splitting up servers on several selection pages - selection menu can now handle up to 999 servers - server announcements now cycle through servers with same grouping like menu if servers are more than 8 - redirection to passworded servers is now possible, either for admins or even normal players - introduced serverlist option "password" which sets the connect password needed for this server - introduced serverlist option "publicpassword": 0 = password not public, only admins can have themselves redirected to this server (if passworded) 1 = password is public, all players can have themselves redirected to this server (if passworded) - optimized performance of redirect_reload - changed some messages that were displayed in console to be displayed in chat area - added a retry queue people can add themselves to with /retry command to be redirected to the server they came from - added command /stopretry to drop out of the retry queue - added many messages and error messages - moved some initialization code from client_putinserver to plugin_cfg to increase performance - added debug messages (english only) that will show in server log when plugin is running in debug mode - fixed a bug where message "player has been redirected to server..." was displayed to all others in the language of the player that has been redirected - fixed a bug where message "player has been redirected here from..." was displayed to all others in the language of the player that has been redirected - added welcome message when a player was redirected from another server - added announcement that the player can use /retry (displayed only if redirected_retry 1 and redirect_show 1) v0.9.1 - fixed a bug where the plugin would try to display a welcome message even if the player was not redirected, causing an error message in AMXX log */ #include <amxmodx> #include <amxmisc> #include <engine> #include <sockets> // plugin defines #define PLUGIN_NAME "Server redirect" #define PLUGIN_VERSION "0.9.1" #define PLUGIN_AUTHOR "x0R" #define PLUGIN_TAG "[REDIRECT]" // maximum values - don't change this if you don't know what you are doing! #define MAX_FILE_LEN 256 // maximum length of file names #define MAX_SERVERLINE_LEN 256 // maximum length of a line read from SERVERFILE #define MAX_SERVERNAME_LEN 50 // maximum length of a server name read from SERVERFILE #define MAX_SERVERADDRESS_LEN 100 // maximum length of a server address read from SERVERFILE #define MAX_NAME_LEN 33 // maximum length of a player name #define MAX_MENUBODY_LEN 512 // maximum length of a menu body #define MAX_INFO_LEN 1500 // maximum length of info reply - when longer than that the packet is fragmented (due to MTU setting) #define MAX_MAP_LEN 30 // maximum length of map names #define MAX_IP_LEN 16 // maximum length of IP addresses #define MAX_PORT_LEN 6 // maximum length of port numbers (as strings of course) #define MAX_KEY_LEN 20 // maximum length of a key name in SERVERFILE #define MAX_PASSWORD_LEN 15 // maximum length of a password in SERVERFILE #define MAX_VALUE_LEN 255 // maximum length of a value in SERVERFILE // unique task ID's - currently not needed but who knows when they will be #define TASKID_QUERY 21934807 #define TASKID_QUERY_RECEIVE 21934808 #define TASKID_ANNOUNCE 21934809 // options - these can be changed by the user, rememeber that you need to recompile for any changes here to take effect #define SERVERFILE "serverlist.ini" // name of file in /configs containing the server forwards - you can also prepend a subdirectory #define QUERY_INTERVAL 20.0 // interval of server querying (in seconds) #define QUERY_TIMEOUT 1.0 // the maximum time to wait for a server answer (in seconds) before it is considered being down #define MAX_SERVERFORWARDS 5 // maximum number of server forwards in forwards file #define MAX_MENUPAGES 10 // maximum number of pages the server selection menu can have #define DEFAULT_CMDBACKUP 2 // how often to resend the UDP request to servers by default #define MENU_FORCENOCOLOR false // false = display colored menues if the mod supports it; true = never display colored menues // positions to get information from in server answer #define STRUCT_INFO_POS_MAP 2 #define STRUCT_INFO_POS_ACTIVEPLAYERS 5 #define STRUCT_INFO_POS_MAXPLAYERS 6 #define STRUCT_INFO_POS_PROTOCOL 7 // server flags #define SERVERFLAG_NOAUTO 0 #define SERVERFLAG_NOMANUAL 1 #define SERVERFLAG_NODISPLAY 2 // --------------------------------------- end of defines --------------------------------------- // global variables new g_saServerNames[MAX_SERVERFORWARDS][MAX_SERVERNAME_LEN] // server names new g_saServerAddresses[MAX_SERVERFORWARDS][MAX_SERVERADDRESS_LEN] // server addresses new g_naServerPorts[MAX_SERVERFORWARDS] = {27015, ...} // server ports new g_saServerPasswords[MAX_SERVERFORWARDS][MAX_PASSWORD_LEN] // server passwords new g_naServerPublicPassword[MAX_SERVERFORWARDS] = {0, ...} // is the server password public? new g_naServerActivePlayers[MAX_SERVERFORWARDS] = {-1, ...} // active players new g_naServerMaxPlayers[MAX_SERVERFORWARDS] = {-1, ...} // maximum players new g_saServerMap[MAX_SERVERFORWARDS][MAX_MAP_LEN] // current map new g_naServerSockets[MAX_SERVERFORWARDS] = {0, ...} // server request sockets new g_naServerCmdBackup[MAX_SERVERFORWARDS] = {DEFAULT_CMDBACKUP, ...} // cmdbackup new g_naServerFlags[MAX_SERVERFORWARDS] = {0, ...} // server flags new g_naServerReserveSlots[MAX_SERVERFORWARDS] = {0, ...} // reserve admin slots on this server? new g_naMenuPageStart[MAX_MENUPAGES] = {0, ...} new bool:g_baServerResponding[MAX_SERVERFORWARDS] = {false, ...} // is server responding? new g_nServerCount = 0 // number of found forward servers new g_nLastRedirectServer = -1 // the last server someone was redirected to - needed for /follow command new g_sLastRedirectName[MAX_NAME_LEN] = "" // the nick of the person who was redirected - needed for /follow command new g_nOwnServer = -1 new g_modname[11] = "" new g_naLastMenuPages[32] = {1, ...} new g_naServerSelections[32][8] new g_nNextAnnounceServer = 0 new g_nLastServers[32] = {-1, ...} new g_nRetryQueue[32][2] new g_nRetryCount = 0 new bool:g_bDebug = false // global CVAR's new cvar_active new cvar_auto new cvar_manual new cvar_follow new cvar_external_address new cvar_check_method new cvar_announce new cvar_announce_mode new cvar_announce_alivepos_x new cvar_announce_alivepos_y new cvar_announce_deadpos_x new cvar_announce_deadpos_y new cvar_show new cvar_adminslots new cvar_maxadmins new cvar_retry // --------------------------------------- end of global vars --------------------------------------- /* public plugin_precache() { } */ #if AMXX_VERSION_NUM >= 170 public plugin_init() { register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR) register_cvar("redirect_version", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY) set_cvar_string("redirect_version", PLUGIN_VERSION) // please see the description at top if you want to know what these CVAR's do cvar_active = register_cvar("redirect_active", "0") cvar_auto = register_cvar("redirect_auto", "0") cvar_manual = register_cvar("redirect_manual", "0") cvar_follow = register_cvar("redirect_follow", "0") cvar_external_address = register_cvar("redirect_external_address", "") cvar_check_method = register_cvar("redirect_check_method", "0") cvar_announce = register_cvar("redirect_announce", "120") cvar_announce_mode = register_cvar("redirect_announce_mode", "3") cvar_announce_alivepos_x = register_cvar("redirect_announce_alivepos_x", "-1.0") cvar_announce_alivepos_y = register_cvar("redirect_announce_alivepos_y", "0.01") cvar_announce_deadpos_x = register_cvar("redirect_announce_deadpos_x", "-1.0") cvar_announce_deadpos_y = register_cvar("redirect_announce_deadpos_y", "0.35") cvar_show = register_cvar("redirect_show", "1") cvar_adminslots = register_cvar("redirect_adminslots", "0") cvar_maxadmins = register_cvar("redirect_maxadmins", "0") cvar_retry = register_cvar("redirect_retry", "0") register_dictionary("redirect.txt") register_dictionary("common.txt") load_servers() register_menu("Redirect Menu", 1023, "server_menu_select") register_srvcmd("redirect_reload", "srvcmd_reload", -1, "- reload redirect servers") register_clcmd("say /server", "cmd_show_server_menu", 0, "- show server redirection menu") register_clcmd("say_team /server", "cmd_show_server_menu", 0, "- show server redirection menu") register_clcmd("pickserver", "cmd_pickserver", 0, "show server redirection menu") register_clcmd("say /follow", "cmd_follow_player", 0, "- follow the last redirected player to his server") register_clcmd("say_team /follow", "cmd_follow_player", 0, "- follow the last redirected player to his server") register_clcmd("say /retry", "cmd_retry", 0, "- redirect back as soon as the foregoing server has a free slot") register_clcmd("say_team /retry", "cmd_retry", 0, "- redirect back as soon as the foregoing server has a free slot") register_clcmd("say /stopretry", "cmd_stopretry", 0, "- stop retrying the foregoing server") register_clcmd("say_team /stopretry", "cmd_stopretry", 0, "- stop retrying the foregoing server") register_clcmd("redirect_announce_now", "announce_servers", ADMIN_KICK , "- announce server list immediately") register_clcmd("redirect_user", "cmd_redirect_user", ADMIN_KICK , "<playername|playerid> [servernum] - redirect a player [to a given server]") set_task(QUERY_INTERVAL, "query_servers", TASKID_QUERY, "", 0, "b") get_modname(g_modname, 10) // check whether we are in debug mode or not new saDummy[2] new saStatus[6] get_plugin(-1, saDummy, 0, saDummy, 0, saDummy, 0, saDummy, 0, saStatus, 5) g_bDebug = bool:equal(saStatus, "debug") } public plugin_cfg() { // if we didn't detect our own server yet now do it once - we can't do this in plugin_init because the cvars are not set there already if (g_nOwnServer == -1) { new sFullAddress[MAX_SERVERADDRESS_LEN] new sTmpServerIP[MAX_IP_LEN + MAX_PORT_LEN] get_cvar_string("net_address", sTmpServerIP, MAX_IP_LEN + MAX_PORT_LEN - 1) new sTmpOwnAddress[MAX_SERVERADDRESS_LEN] get_pcvar_string(cvar_external_address, sTmpOwnAddress, MAX_SERVERADDRESS_LEN - 1) new nServerCount = 0 while (nServerCount < g_nServerCount) { format(sFullAddress, MAX_SERVERADDRESS_LEN - 1, "%s:%d", g_saServerAddresses[nServerCount], g_naServerPorts[nServerCount]) if (equal(sFullAddress, sTmpOwnAddress) || equal(sFullAddress, sTmpServerIP)) { g_nOwnServer = nServerCount break } nServerCount++ } } if (g_nOwnServer == -1) // we don't know who we are so do nothing return PLUGIN_CONTINUE if (get_pcvar_float(cvar_announce) > 0.0) if (!task_exists(TASKID_ANNOUNCE)) set_task(get_pcvar_float(cvar_announce), "announce_servers", TASKID_ANNOUNCE, "", 0, "b") return PLUGIN_CONTINUE } public plugin_natives() { register_native ("redirect", "native_redirect", 1) } public plugin_modules() { require_module("engine") require_module("sockets") } // load servers from file public bool:load_servers() { new sConfigDir[MAX_FILE_LEN], sServerFile[MAX_FILE_LEN] get_configsdir(sConfigDir, MAX_FILE_LEN-1) format(sServerFile, MAX_FILE_LEN-1, "%s/%s", sConfigDir, SERVERFILE) if (!file_exists(sServerFile)) { log_amx("%L", LANG_SERVER, "MSG_ERROR_NO_FILE", sServerFile) return false } new nFilePos = 0 new sFileLine[MAX_SERVERLINE_LEN] new nReadLen new sPort[MAX_PORT_LEN] new sKey[MAX_KEY_LEN] new sValue[MAX_VALUE_LEN] new nCurrentServer = -1 while (read_file(sServerFile, nFilePos++, sFileLine, MAX_SERVERLINE_LEN-1, nReadLen)) { if ((sFileLine[0] == ';') && (strcmp(sFileLine, "") == 0)) continue // skip comment and empty lines if ((sFileLine[0] == '[') && (sFileLine[strlen(sFileLine) - 1] == ']')) // a section starts { nCurrentServer++ if (nCurrentServer > 0) { // check whether the previous server was valid if ((g_naServerPorts[nCurrentServer - 1] != 0) && (strcmp(g_saServerAddresses[nCurrentServer - 1], "") != 0)) { g_nServerCount++ num_to_str(g_naServerPorts[nCurrentServer - 1], sPort, MAX_PORT_LEN - 1) log_amx("%L", LANG_SERVER, "MSG_LOADED_SERVER", g_saServerNames[nCurrentServer - 1], g_saServerAddresses[nCurrentServer - 1], sPort) } else nCurrentServer-- } if (nCurrentServer >= MAX_SERVERFORWARDS) break; copy(g_saServerNames[nCurrentServer], strlen(sFileLine) - 2, sFileLine[1]) continue } if (nCurrentServer >= 0) // do we already have found a section? { strtok(sFileLine, sKey, MAX_KEY_LEN - 1, sValue, MAX_VALUE_LEN - 1, '=', 1) strtoupper(sKey) if (strcmp(sKey, "ADDRESS") == 0) copy(g_saServerAddresses[nCurrentServer], MAX_SERVERADDRESS_LEN - 1, sValue) else if (strcmp(sKey, "PASSWORD") == 0) copy(g_saServerPasswords[nCurrentServer], MAX_PASSWORD_LEN - 1, sValue) else if (strcmp(sKey, "PUBLICPASSWORD") == 0) { if (is_str_num(sValue)) if (str_to_num(sValue) == 1) g_naServerPublicPassword[nCurrentServer] = 1 } else if (strcmp(sKey, "PORT") == 0) { if (is_str_num(sValue)) g_naServerPorts[nCurrentServer] = str_to_num(sValue) else g_naServerPorts[nCurrentServer] = 27015 if ((g_naServerPorts[nCurrentServer] > 65536) || (g_naServerPorts[nCurrentServer] < 1024)) g_naServerPorts[nCurrentServer] = 27015 } else if (strcmp(sKey, "CMDBACKUP") == 0) { if (is_str_num(sValue)) g_naServerCmdBackup[nCurrentServer] = str_to_num(sValue) else g_naServerCmdBackup[nCurrentServer] = DEFAULT_CMDBACKUP // protect from insane values if ((g_naServerCmdBackup[nCurrentServer] > 200) || (g_naServerCmdBackup[nCurrentServer] < 0)) g_naServerCmdBackup[nCurrentServer] = DEFAULT_CMDBACKUP } else if (strcmp(sKey, "NOAUTO") == 0) { if (is_str_num(sValue)) if (str_to_num(sValue) == 1) g_naServerFlags[nCurrentServer] = g_naServerFlags[nCurrentServer] | (1<<SERVERFLAG_NOAUTO) } else if (strcmp(sKey, "NOMANUAL") == 0) { if (is_str_num(sValue)) if (str_to_num(sValue) == 1) g_naServerFlags[nCurrentServer] = g_naServerFlags[nCurrentServer] | (1<<SERVERFLAG_NOMANUAL) } else if (strcmp(sKey, "NODISPLAY") == 0) { if (is_str_num(sValue)) if (str_to_num(sValue) == 1) g_naServerFlags[nCurrentServer] = g_naServerFlags[nCurrentServer] | (1<<SERVERFLAG_NODISPLAY) } else if (strcmp(sKey, "ADMINSLOTS") == 0) { if (is_str_num(sValue)) g_naServerReserveSlots[nCurrentServer] = str_to_num(sValue) else g_naServerReserveSlots[nCurrentServer] = 0 if ((g_naServerReserveSlots[nCurrentServer] > 32) || (g_naServerReserveSlots[nCurrentServer] < 0)) g_naServerReserveSlots[nCurrentServer] = 0 } } } if ((nCurrentServer >= MAX_SERVERFORWARDS) || (nCurrentServer == -1)) return true; // check whether the previous server was valid if ((g_naServerPorts[nCurrentServer] != 0) && (strcmp(g_saServerAddresses[nCurrentServer], "") != 0)) { g_nServerCount++ num_to_str(g_naServerPorts[nCurrentServer], sPort, MAX_PORT_LEN - 1) log_amx("%L", LANG_SERVER, "MSG_LOADED_SERVER", g_saServerNames[nCurrentServer], g_saServerAddresses[nCurrentServer], sPort) } if (g_nServerCount < 2) { log_amx("%L", LANG_SERVER, "MSG_ERROR_NOT_ENOUGH_SERVERS") return false } return true } public bool:can_redirect(nServerNum) { new nCheckMethod = get_pcvar_num(cvar_check_method) new nAutoMode = get_pcvar_num(cvar_auto) new bool:bReturn = false if ((nServerNum != g_nOwnServer) && (nServerNum >= 0) && (nServerNum < MAX_SERVERFORWARDS)) { if ((nAutoMode == 0) || (g_naServerFlags[nServerNum] & (1<<SERVERFLAG_NOAUTO))) return false switch (nCheckMethod) { case 0: bReturn = true case 1: bReturn = g_baServerResponding[nServerNum] case 2: bReturn = (g_baServerResponding[nServerNum] && ((g_naServerActivePlayers[nServerNum] + 1) < g_naServerMaxPlayers[nServerNum])) } } return bReturn } public queue_add(id, nServer) { if (g_bDebug) log_amx("added player %i to queue for server %i in slot %i", id, nServer, g_nRetryCount) g_nRetryQueue[g_nRetryCount][0] = id g_nRetryQueue[g_nRetryCount][1] = nServer g_nRetryCount++ } public queue_remove(id) { new nCount = 0 while (nCount < g_nRetryCount) { if (g_nRetryQueue[nCount][0] == id) { // ok, remove from queue and let all others go one place up // in case it's the last entry in queue where the following loop would never be executed if (g_bDebug) log_amx("removed player %i from queue of server %i, slot %i", id, g_nRetryQueue[nCount][1], nCount) g_nRetryQueue[nCount][0] = -1 g_nRetryQueue[nCount][1] = -1 // move other entries up while ((nCount + 1) < g_nRetryCount) { g_nRetryQueue[nCount][0] = g_nRetryQueue[nCount + 1][0] g_nRetryQueue[nCount][1] = g_nRetryQueue[nCount + 1][1] nCount++ } g_nRetryCount-- break } nCount++ } } public reset_info(id[]) { client_cmd(id[0], "setinfo ^"sredir^" ^"^"") client_cmd(id[0], "setinfo ^"password^" ^"^"") } public announce_servers() { if (get_pcvar_num(cvar_active) == 1) { if (g_nServerCount > 0) { new nCheckMethod = get_pcvar_num(cvar_check_method) new sAnnounceBody[MAX_MENUBODY_LEN] = "" new nDisplayCount = 0 new nServerCount = g_nNextAnnounceServer if (nServerCount >= g_nServerCount) nServerCount = 0 while ((nServerCount < g_nServerCount) && (nDisplayCount < 8)) { if (!(g_naServerFlags[nServerCount] & (1<<SERVERFLAG_NODISPLAY))) { if (nServerCount == g_nOwnServer) { if ((nCheckMethod == 0) || (nCheckMethod == 1)) format(sAnnounceBody, MAX_MENUBODY_LEN - 1, "%s^n%s(%s)", sAnnounceBody, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else if (nCheckMethod == 2) { new sMap[MAX_MAP_LEN] get_mapname(sMap, MAX_MAP_LEN - 1) format(sAnnounceBody, MAX_MENUBODY_LEN - 1, "%s^n%s [%s] (%d/%d)", sAnnounceBody, g_saServerNames[nServerCount], sMap, get_playersnum(1), get_maxplayers()) } } else { if (nCheckMethod == 0) format(sAnnounceBody, MAX_MENUBODY_LEN - 1, "%s^n%s(%s)", sAnnounceBody, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else if (g_baServerResponding[nServerCount]) { if (nCheckMethod == 1) format(sAnnounceBody, MAX_MENUBODY_LEN - 1, "%s^n%s(%s)", sAnnounceBody, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else if (nCheckMethod == 2) format(sAnnounceBody, MAX_MENUBODY_LEN - 1, "%s^n%s [%s] (%d/%d)", sAnnounceBody, g_saServerNames[nServerCount], g_saServerMap[nServerCount], g_naServerActivePlayers[nServerCount], g_naServerMaxPlayers[nServerCount]) } else format(sAnnounceBody, MAX_MENUBODY_LEN - 1, "%s^n%s (down)", sAnnounceBody, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) } } nServerCount++ nDisplayCount++ } g_nNextAnnounceServer = nServerCount set_hudmessage(000, 100, 255, -1.0, 0.01, 0, 0.0, 10.0, 0.5, 0.10, 1) //show_hudmessage(0, sAnnounceBody) if (get_pcvar_float(cvar_announce) > 0.0) { new nAnnounceMode = get_pcvar_num(cvar_announce_mode) if (nAnnounceMode > 0) { new nPlayers[32] new nPlayerNum, nPlayerCount new sAnnounceText[MAX_MENUBODY_LEN] if ((nAnnounceMode == 1) || (nAnnounceMode == 3)) { get_players(nPlayers, nPlayerNum, "ac") // alive players set_hudmessage(000, 100, 255, get_pcvar_float(cvar_announce_alivepos_, get_pcvar_float(cvar_announce_alivepos_y), 0, 0.0, 10.0, 0.5, 0.10, 1) for (nPlayerCount = 0; nPlayerCount < nPlayerNum; nPlayerCount++) { if (get_pcvar_num(cvar_manual) == 1) format(sAnnounceText, MAX_MENUBODY_LEN - 1, "%L^n%s", nPlayers[nPlayerCount], "MSG_SAY_SERVER", sAnnounceBody) else sAnnounceText = sAnnounceBody show_hudmessage(nPlayers[nPlayerCount], sAnnounceText) } } if ((nAnnounceMode == 2) || (nAnnounceMode == 3)) { get_players(nPlayers, nPlayerNum, "bc") // dead players set_hudmessage(000, 100, 255, get_pcvar_float(cvar_announce_deadpos_, get_pcvar_float(cvar_announce_deadpos_y), 0, 0.0, 10.0, 0.5, 0.10, 1) // show list at lower position for them so it is not covered by the "spectator bars" for (nPlayerCount = 0; nPlayerCount < nPlayerNum; nPlayerCount++) { if (get_pcvar_num(cvar_manual) == 1) format(sAnnounceText, MAX_MENUBODY_LEN - 1, "%L^n%s", nPlayers[nPlayerCount], "MSG_SAY_SERVER", sAnnounceBody) else sAnnounceText = sAnnounceBody show_hudmessage(nPlayers[nPlayerCount], sAnnounceText) } } } } } } return PLUGIN_HANDLED } public show_server_menu(id, menupage) { new nServerCount if (get_pcvar_num(cvar_active) == 1) { if (g_nServerCount > 0) { new bColorMenu = (colored_menus() && !MENU_FORCENOCOLOR) new nCheckMethod = get_pcvar_num(cvar_check_method) new sMenuBody[MAX_MENUBODY_LEN] if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "\r%L\R^n", id, "MSG_SELECT_SERVER") else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%L^n", id, "MSG_SELECT_SERVER") if (menupage <= 1) nServerCount = 0 else nServerCount = g_naMenuPageStart[menupage - 2] new nDisplayNumber = 1 new key = (1<<9) while ((nDisplayNumber < 9) && (nServerCount < g_nServerCount)) { if (!(g_naServerFlags[nServerCount] & (1<<SERVERFLAG_NODISPLAY))) { new bool:bCanRedirectByPassword = !(!equal(g_saServerPasswords[nServerCount], "") && (g_naServerPublicPassword[nServerCount] == 0) && (!access(id, ADMIN_RESERVATION))) if ((g_naServerFlags[nServerCount] & (1<<SERVERFLAG_NOMANUAL)) || !bCanRedirectByPassword) { if (nCheckMethod == 2) if (g_baServerResponding[nServerCount]) if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \d %s [%s] (%d/%d)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerMap[nServerCount], g_naServerActivePlayers[nServerCount], g_naServerMaxPlayers[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s [%s] (%d/%d)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerMap[nServerCount], g_naServerActivePlayers[nServerCount], g_naServerMaxPlayers[nServerCount]) else if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \d %s (down)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s (down)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \d %s(%s)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s(%s)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) } else if (nServerCount == g_nOwnServer) { if (nCheckMethod == 2) { new sMap[MAX_MAP_LEN] get_mapname(sMap, MAX_MAP_LEN - 1) if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \d %s [%s] (%d/%d)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], sMap, get_playersnum(1), get_maxplayers()) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s [%s] (%d/%d)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], sMap, get_playersnum(1), get_maxplayers()) } else if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \d %s(%s)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s(%s)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) } else { if (nCheckMethod == 0) { if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \w %s\y(\w%s\y)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s(%s)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) key = key | (1<<(nDisplayNumber - 1)) g_naServerSelections[id][nDisplayNumber - 1] = nServerCount } else if (g_baServerResponding[nServerCount]) { if (nCheckMethod == 1) { if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \w %s\y(\w%s\y)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s(%s)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) key = key | (1<<(nDisplayNumber - 1)) g_naServerSelections[id][nDisplayNumber - 1] = nServerCount } else if (nCheckMethod == 2) { if (((g_naServerActivePlayers[nServerCount] == (g_naServerMaxPlayers[nServerCount] - 1)) && (g_naServerReserveSlots[nServerCount] > 0) && (!access(id, ADMIN_RESERVATION))) || (g_naServerActivePlayers[nServerCount] >= g_naServerMaxPlayers[nServerCount])) if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \w %s \y[\w%s\y] \r(\w%d/%d\r)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerMap[nServerCount], g_naServerActivePlayers[nServerCount], g_naServerMaxPlayers[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s [%s] (%d/%d)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerMap[nServerCount], g_naServerActivePlayers[nServerCount], g_naServerMaxPlayers[nServerCount]) else { if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \w %s \y[\w%s\y] \y(\w%d/%d\y)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerMap[nServerCount], g_naServerActivePlayers[nServerCount], g_naServerMaxPlayers[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s [%s] (%d/%d)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerMap[nServerCount], g_naServerActivePlayers[nServerCount], g_naServerMaxPlayers[nServerCount]) key = key | (1<<(nDisplayNumber - 1)) g_naServerSelections[id][nDisplayNumber - 1] = nServerCount } } } else { if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n\y%d. \d %s \r(\ddown\r)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n%d. %s (down)", sMenuBody, nDisplayNumber, g_saServerNames[nServerCount], g_saServerAddresses[nServerCount]) } } nDisplayNumber++ } nServerCount++ } if (nServerCount < g_nServerCount) { if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n^n\y9.\w %L", sMenuBody, id, "MSG_MORE") else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n^n9. %L", sMenuBody, id, "MSG_MORE") key = key | (1<<8) } else { if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n^n\y9.\d %L", sMenuBody, id, "MSG_MORE") else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n^n9. %L", sMenuBody, id, "MSG_MORE") } if (bColorMenu) format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n^n\y0.\w %L", sMenuBody, id, "MSG_CANCEL") else format(sMenuBody, MAX_MENUBODY_LEN - 1, "%s^n^n0. %L", sMenuBody, id, "MSG_CANCEL") show_menu(id, key, sMenuBody, -1, "Redirect Menu") } } g_naMenuPageStart[menupage - 1] = nServerCount g_naLastMenuPages[id] = menupage } public srvcmd_reload() { new nCounter // clear all global arrays and variables before reloading for (nCounter = 0; nCounter < MAX_SERVERFORWARDS; nCounter++) { g_naServerPorts[nCounter] = 27015 g_naServerActivePlayers[nCounter] = -1 g_naServerMaxPlayers[nCounter] = -1 g_naServerSockets[nCounter] = 0 g_naServerCmdBackup[nCounter] = DEFAULT_CMDBACKUP g_naServerFlags[nCounter] = 0 g_naServerReserveSlots[nCounter] = 0 g_baServerResponding[nCounter] = false g_saServerMap[nCounter] = "" g_saServerNames[nCounter] = "" g_saServerAddresses[nCounter] = "" g_saServerPasswords[nCounter] = "" g_naServerPublicPassword[nCounter] = 0 } // reset global variables g_nNextAnnounceServer = 0 g_nServerCount = 0 g_nLastRedirectServer = -1 g_sLastRedirectName = "" g_nOwnServer = -1 g_nRetryCount = 0 for (new nPlrCnt = 0; nPlrCnt < 32; nPlrCnt++) { // server IDs might change and thus render all currently saved server IDs invalid, so remove them, to be sure g_nRetryQueue[nPlrCnt][0] = -1 g_nRetryQueue[nPlrCnt][1] = -1 g_nLastServers[nPlrCnt] = -1 } load_servers() new sFullAddress[MAX_SERVERADDRESS_LEN] new sTmpServerIP[MAX_IP_LEN + MAX_PORT_LEN] get_cvar_string("net_address", sTmpServerIP, MAX_IP_LEN + MAX_PORT_LEN - 1) new sTmpOwnAddress[MAX_SERVERADDRESS_LEN] get_pcvar_string(cvar_external_address, sTmpOwnAddress, MAX_SERVERADDRESS_LEN - 1) // define the own server again new nServerCount = 0 while (nServerCount < g_nServerCount) { format(sFullAddress, MAX_SERVERADDRESS_LEN - 1, "%s:%d", g_saServerAddresses[nServerCount], g_naServerPorts[nServerCount]) if (equal(sFullAddress, sTmpOwnAddress) || equal(sFullAddress, sTmpServerIP)) { g_nOwnServer = nServerCount break } nServerCount++ } if (g_nOwnServer == -1) log_amx("%L", LANG_SERVER, "MSG_OWN_DETECTION_ERROR") } // needed so server doesn't display "unknown command: pickserver" (returning PLUGIN_HANDLED in cmd_show_server_menu would supress the chat message) public cmd_pickserver(id, level, cid) { cmd_show_server_menu(id, level, cid) return PLUGIN_HANDLED } /* bCanOther = if nServer is no valid redirect target can we use another server instead? bCanDrop = drop user if no server was found? bIgnoreSource = redirect regardless of redirecting would be back to source server */ public redirect(id, nServer, bCanOther, bCanDrop, bIgnoreSource) { new nForwardServer = -1 new bool:bFoundServer = false new bAdminAccess = access(id, ADMIN_RESERVATION) new nSourceServer if (bIgnoreSource) nSourceServer = -1 else { new sSourceServer[3] get_user_info(id, "sredir", sSourceServer, 2) if (!is_str_num(sSourceServer)) nSourceServer = -1 else nSourceServer = str_to_num(sSourceServer) if ((nSourceServer < 0) || (nSourceServer >= g_nServerCount)) nSourceServer = -1 } new bool:bCanRedirectByPassword = false if (nServer != -1) bCanRedirectByPassword = !(!equal(g_saServerPasswords[nServer], "") && (g_naServerPublicPassword[nServer] == 0) && (!bAdminAccess)) if (!can_redirect(nServer) || (!bCanRedirectByPassword)) { if (!bCanOther) { if (bCanDrop) { client_cmd(id, "echo %s: %L", PLUGIN_TAG, id, "MSG_NO_REDIRECT_SERVER") client_cmd(id, "disconnect") } return false } nForwardServer = 0 // make sure at least one valid server exists or the second loop could be endless while (nForwardServer < g_nServerCount) { bCanRedirectByPassword = !(!equal(g_saServerPasswords[nForwardServer], "") && (g_naServerPublicPassword[nForwardServer] == 0) && (!bAdminAccess)) if (can_redirect(nForwardServer) && bCanRedirectByPassword && (nForwardServer != nSourceServer)) { bFoundServer = true break } nForwardServer++ } if (get_pcvar_num(cvar_auto) == 1) nForwardServer = -1 } else { nForwardServer = nServer bFoundServer = true } if (bFoundServer) { while (nForwardServer == -1) { nForwardServer = random_num(0, g_nServerCount - 1) bCanRedirectByPassword = !(!equal(g_saServerPasswords[nForwardServer], "") && (g_naServerPublicPassword[nForwardServer] == 0) && (!bAdminAccess)) if (!can_redirect(nForwardServer) || !bCanRedirectByPassword || ((nForwardServer == nSourceServer))) nForwardServer = -1 } new sUserNick[MAX_NAME_LEN] get_user_name(id, sUserNick, MAX_NAME_LEN - 1) client_cmd(id, "setinfo ^"sredir^" ^"%d^"", g_nOwnServer) if (!equal(g_saServerPasswords[nForwardServer], "")) // set the user's server connect password if needed client_cmd(id, "setinfo ^"password^" ^"%s^"", g_saServerPasswords[nForwardServer]) new sFullAddress[MAX_SERVERADDRESS_LEN] format(sFullAddress, MAX_SERVERADDRESS_LEN - 1, "%s:%d", g_saServerAddresses[nForwardServer], g_naServerPorts[nForwardServer]) client_cmd(id, "connect %s", sFullAddress) if (get_pcvar_num(cvar_show) == 1) { new nPlayers[32] new nPlayerNum, nPlayerCount, nCurrentPlayer get_players(nPlayers, nPlayerNum, "c") set_hudmessage(000, 100, 255, get_pcvar_float(cvar_announce_alivepos_, get_pcvar_float(cvar_announce_alivepos_y), 0, 0.0, 10.0, 0.5, 0.10, 1) for (nPlayerCount = 0; nPlayerCount < nPlayerNum; nPlayerCount++) { nCurrentPlayer = nPlayers[nPlayerCount] if (get_pcvar_num(cvar_follow) == 1) client_print(nCurrentPlayer, print_chat, "%s: %L - %L", PLUGIN_TAG, nCurrentPlayer, "MSG_REDIRECTED", sUserNick, g_saServerNames[nForwardServer], nCurrentPlayer, "MSG_FOLLOW") else client_print(nCurrentPlayer, print_chat, "%s: %L", PLUGIN_TAG, nCurrentPlayer, "MSG_REDIRECTED", sUserNick, g_saServerNames[nForwardServer]) } } g_nLastRedirectServer = nForwardServer g_sLastRedirectName = sUserNick } else if (bCanDrop) { client_cmd(id, "echo %s: %L", PLUGIN_TAG, id, "MSG_NO_REDIRECT_SERVER") client_cmd(id, "disconnect") } return true } public native_redirect(id, nServer, bCanDrop) { redirect(id, nServer, (nServer == -1), bCanDrop, true) return PLUGIN_HANDLED } public cmd_redirect_user(id, level, cid) { if (!cmd_access(id, level, cid, 2)) return PLUGIN_HANDLED new nForwardServer = -1 new sName[32] read_argv(1, sName, 31) new nCmdID = cmd_target(id, sName, 8) if (!nCmdID) return PLUGIN_HANDLED // contains destination server number? if (read_argc() > 2) { new argtmp[3] read_argv(2, argtmp, 2) if (is_str_num(argtmp)) nForwardServer = (str_to_num(argtmp) - 1) } redirect(nCmdID, nForwardServer, (nForwardServer == -1), true, true) return PLUGIN_HANDLED } public cmd_show_server_menu(id, level, cid) { if (get_pcvar_num(cvar_manual) == 1) show_server_menu(id, 1) else client_print(id, print_chat, "%s: %L", PLUGIN_TAG, id, "MSG_MANUAL_DISABLED") return PLUGIN_CONTINUE } public cmd_retry(id, level, cid) { if (get_pcvar_num(cvar_retry) > 0) { if (g_nLastServers[id] > -1) { client_print(id, print_chat, "%s: %L", PLUGIN_TAG, id, "MSG_QUEUE_ADD", g_nRetryCount + 1, g_saServerNames[g_nLastServers[id]]) queue_add(id, g_nLastServers[id]) } else { if (g_bDebug) log_amx("last server for player %i is server %i", id, g_nLastServers[id]) client_print(id, print_chat, "%s: %L", PLUGIN_TAG, id, "MSG_QUEUE_NO_LAST") } } else { client_print(id, print_chat, "%s: %L", PLUGIN_TAG, id, "MSG_QUEUE_DEACTIVATED") } } public cmd_stopretry(id, level, cid) { client_print(id, print_chat, "%s: %L", PLUGIN_TAG, id, "MSG_QUEUE_REMOVE", g_saServerNames[g_nLastServers[id]]) queue_remove(id) } public cmd_follow_player(id, level, cid) { if (get_pcvar_num(cvar_active) == 1) { if (get_pcvar_num(cvar_follow) == 1) { if (g_nLastRedirectServer >= 0) { new sFullAddress[MAX_SERVERADDRESS_LEN] format(sFullAddress, MAX_SERVERADDRESS_LEN - 1, "%s:%d", g_saServerAddresses[g_nLastRedirectServer], g_naServerPorts[g_nLastRedirectServer]) console_print(id, "%s: %L", PLUGIN_TAG, id, "MSG_REDIRECTING", g_saServerNames[g_nLastRedirectServer]) client_cmd(id, "connect %s", sFullAddress) new sUserNick[MAX_NAME_LEN] get_user_name(id, sUserNick, MAX_NAME_LEN - 1) if (get_pcvar_num(cvar_show) == 1) client_print(0, print_chat, "%s: %L - %L", PLUGIN_TAG, id, "MSG_FOLLOWED", sUserNick, g_sLastRedirectName, g_saServerNames[g_nLastRedirectServer], id, "MSG_FOLLOW") g_sLastRedirectName = sUserNick } else client_print(id, print_chat, "%s: %L", PLUGIN_TAG, id, "MSG_CANT_FOLLOW") } else client_print(id, print_chat, "%s: %L", PLUGIN_TAG, id, "MSG_FOLLOW_DISABLED") } return PLUGIN_CONTINUE } public server_menu_select(id, key) { if (key < 8) { new nServerIdx = g_naServerSelections[id][key] new sFullAddress[MAX_SERVERADDRESS_LEN] format(sFullAddress, MAX_SERVERADDRESS_LEN - 1, "%s:%d", g_saServerAddresses[nServerIdx], g_naServerPorts[nServerIdx]) console_print(id, "%s: %L", PLUGIN_TAG, id, "MSG_REDIRECTING", g_saServerNames[nServerIdx]) new sUserNick[MAX_NAME_LEN] get_user_name(id, sUserNick, MAX_NAME_LEN - 1) if (!equal(g_saServerPasswords[nServerIdx], "")) // set the user's server connect password if needed client_cmd(id, "setinfo ^"password^" ^"%s^"", g_saServerPasswords[nServerIdx]) client_cmd(id, "setinfo ^"sredir^" ^"%d^"", g_nOwnServer) client_cmd(id, "connect %s", sFullAddress) if (get_pcvar_num(cvar_show) == 1) { new nPlayers[32] new nPlayerNum, nPlayerCount, nCurrentPlayer get_players(nPlayers, nPlayerNum, "c") set_hudmessage(000, 100, 255, get_pcvar_float(cvar_announce_alivepos_, get_pcvar_float(cvar_announce_alivepos_y), 0, 0.0, 10.0, 0.5, 0.10, 1) for (nPlayerCount = 0; nPlayerCount < nPlayerNum; nPlayerCount++) { nCurrentPlayer = nPlayers[nPlayerCount] if (get_pcvar_num(cvar_follow) == 1) client_print(nCurrentPlayer, print_chat, "%s: %L - %L", PLUGIN_TAG, nCurrentPlayer, "MSG_REDIRECTED", sUserNick, g_saServerNames[nServerIdx], nCurrentPlayer, "MSG_FOLLOW") else client_print(nCurrentPlayer, print_chat, "%s: %L", PLUGIN_TAG, nCurrentPlayer, "MSG_REDIRECTED", sUserNick, g_saServerNames[nServerIdx]) } } g_nLastRedirectServer = nServerIdx g_sLastRedirectName = sUserNick } else { if (key == 8) show_server_menu(id, g_naLastMenuPages[id] + 1) } } public query_servers() { new nCheckMethod = get_pcvar_num(cvar_check_method) if (nCheckMethod == 0) return PLUGIN_HANDLED new socket_error new sOldRequest[9] new sNewRequest[25] if (nCheckMethod == 1) // ping format didn't change for new style queries so one query for all servers format(sOldRequest, 9, "%c%c%c%c%s", 255, 255, 255, 255, "ping") else if (nCheckMethod == 2) { // we don't know what server it is so send both old and new style query format(sOldRequest, 9, "%c%c%c%c%s", 255, 255, 255, 255, "info") format(sNewRequest, 24, "%c%c%c%c%s", 255, 255, 255, 255, "TSource Engine Query") } new nServerCount = 0 new QuerySocket new nCmdBackup new nSendCount while (nServerCount < g_nServerCount) { if (nServerCount != g_nOwnServer) { QuerySocket = socket_open(g_saServerAddresses[nServerCount], g_naServerPorts[nServerCount], SOCKET_UDP, socket_error) if ((QuerySocket > 0) && (socket_error == 0)) { g_naServerSockets[nServerCount] = QuerySocket nCmdBackup = g_naServerCmdBackup[nServerCount] for (nSendCount = -1; nSendCount < nCmdBackup; nSendCount++) socket_send(QuerySocket, sOldRequest, 9) if (nCheckMethod == 2) for (nSendCount = -1; nSendCount < nCmdBackup; nSendCount++) socket_send(QuerySocket, sNewRequest, 25) } else { g_naServerSockets[nServerCount] = 0 log_amx("%L", LANG_SERVER, "MSG_SOCKET_ERROR", socket_error, QuerySocket, nServerCount) } } nServerCount++ } set_task(QUERY_TIMEOUT, "receive_serverquery_answers", TASKID_QUERY_RECEIVE) return PLUGIN_HANDLED } public receive_serverquery_answers() { new nCheckMethod = get_pcvar_num(cvar_check_method) new sRcvBuf[MAX_INFO_LEN] new nCharCnt new nStructPos new nActivePlayers new nMaxPlayers new nClearCounter new nRcvLen new nRecvCount new sMap[MAX_MAP_LEN] new nServerCount = 0 while (nServerCount < g_nServerCount) { if (!g_naServerSockets[nServerCount]) { g_baServerResponding[nServerCount] = false /* should only happen for the g_nOwnServer client_print(0, print_chat, "%s no socket", g_saServerNames[nServerCount]) */ } else { nRecvCount = 0 new nCmdBackup = g_naServerCmdBackup[nServerCount] g_baServerResponding[nServerCount] = false while (socket_change(g_naServerSockets[nServerCount], 1) && (nRecvCount <= nCmdBackup)) { nRecvCount++ // initialize our receive buffer for (nClearCounter = 0; nClearCounter < MAX_INFO_LEN; nClearCounter++) sRcvBuf[nClearCounter] = 0 nRcvLen = socket_recv(g_naServerSockets[nServerCount], sRcvBuf, MAX_INFO_LEN) //log_amx("finished receiving from socket %i (%s), received %i bytes", g_naServerSockets[nServerCount], g_saServerNames[nServerCount], nRcvLen) if (nRcvLen > 5) // shortest reply is a ping response with length of 6 { if (nCheckMethod == 1) { // ping response if (equal(sRcvBuf, {-1,-1,-1,-1,'j'}, 5)) { g_baServerResponding[nServerCount] = true break } } else if (nCheckMethod == 2) { if (equal(sRcvBuf, {-1,-1,-1,-1}, 4)) { // old style HL1 response || new style HL1 response if ((sRcvBuf[4] == 'C') || ((sRcvBuf[4] == 'm'))) { g_baServerResponding[nServerCount] = true nStructPos = 0 nCharCnt = 0 while ((nStructPos < STRUCT_INFO_POS_MAXPLAYERS) && (nCharCnt < MAX_INFO_LEN)) { if (equal(sRcvBuf[nCharCnt], {0})) { nStructPos++ switch (nStructPos) { case STRUCT_INFO_POS_MAP: { copyc(sMap, MAX_MAP_LEN - 1, sRcvBuf[nCharCnt + 1], 0) g_saServerMap[nServerCount] = sMap } case STRUCT_INFO_POS_ACTIVEPLAYERS: { nActivePlayers = int:sRcvBuf[nCharCnt + 1] g_naServerActivePlayers[nServerCount] = nActivePlayers nMaxPlayers = int:sRcvBuf[nCharCnt + 2] g_naServerMaxPlayers[nServerCount] = nMaxPlayers break } } } nCharCnt++ } break } } } } } /* if (nRecvCount == 0) log_amx("no change on socket %i (%s)", g_naServerSockets[nServerCount], g_saServerNames[nServerCount]) */ socket_close(g_naServerSockets[nServerCount]) g_naServerSockets[nServerCount] = 0 } nServerCount++ } if (get_pcvar_num(cvar_retry) > 0) { // now search for players who queued themselves to be redirected (/retry) new bool:bCanRedirectByPassword = false new bAdminAccess new nServer new nPlrCnt = 0 while (nPlrCnt < g_nRetryCount) { nServer = g_nRetryQueue[nPlrCnt][1] if (nServer > -1) // just to be sure { new nPlr = g_nRetryQueue[nPlrCnt][0] bAdminAccess = access(nPlr, ADMIN_RESERVATION) bCanRedirectByPassword = !(!equal(g_saServerPasswords[nServer], "") && (g_naServerPublicPassword[nServer] == 0) && (!bAdminAccess)) if (can_redirect(nServer) && bCanRedirectByPassword) { console_print(nPlr, "%s: %L", PLUGIN_TAG, nPlr, "MSG_RETRY_SUCCESS") redirect(nPlr, nServer, false, false, true) g_naServerActivePlayers[nServer]++ } } nPlrCnt++ } } return PLUGIN_HANDLED } public get_admin_count() { new nPlayers[32] new nPlayerNum, nPlayerCount get_players(nPlayers, nPlayerNum, "ch") new nAdmins = 0 for (nPlayerCount = 0; nPlayerCount < nPlayerNum; nPlayerCount++) { if (access(nPlayers[nPlayerCount], ADMIN_RESERVATION)) nAdmins++ } return nAdmins } public client_disconnect(id) { queue_remove(id) g_nLastServers[id] = -1 } public client_authorized(id) { if (g_nOwnServer == -1) // we don't know who we are so do nothing return PLUGIN_CONTINUE g_naLastMenuPages[id] = 1 new nAutoMode = get_pcvar_num(cvar_auto) if (get_pcvar_num(cvar_active) == 1) { if (nAutoMode > 0) { if ((get_maxplayers() - get_playersnum(1)) == 0) { if (g_nServerCount > 0) { new nMaxAdmins = get_pcvar_num(cvar_maxadmins) if (nMaxAdmins == 0) nMaxAdmins = 32 if ((!access(id, ADMIN_RESERVATION)) || (get_pcvar_num(cvar_adminslots) == 0) || (get_admin_count() > nMaxAdmins)) { redirect(id, -1, true, true, false) return PLUGIN_CONTINUE } else { // find the user that is connected for the shortest time and redirect him new nPlayers[32] new nPlayerNum, nPlayerCount new nMinConnectedTime = 0x7FFFFFFF new nMinTimePlayer = 0 new nUserTime get_players(nPlayers, nPlayerNum, "ch") new nCurID for (nPlayerCount = 0; nPlayerCount < nPlayerNum; nPlayerCount++) { nCurID = nPlayers[nPlayerCount] nUserTime = get_user_time(nCurID) if ((nUserTime < nMinConnectedTime) && (!access(nCurID, ADMIN_RESERVATION))) { nMinTimePlayer = nCurID nMinConnectedTime = nUserTime } } if (nMinTimePlayer != 0) { redirect(nMinTimePlayer, -1, true, true, true) return PLUGIN_CONTINUE } } } } } } new sSourceServer[4] // maximum is 999 servers, so we have a maximum of 3 digits get_user_info(id, "sredir", sSourceServer, 3) if (strcmp(sSourceServer, "") != 0) { new nSourceServer = str_to_num(sSourceServer) g_nLastServers[id] = nSourceServer if (g_bDebug) log_amx("saved last server for player %i as server %i", id, g_nLastServers[id]) if ((nSourceServer >= 0) && (nSourceServer < g_nServerCount)) { if (get_pcvar_num(cvar_show) == 1) { new nPlayers[32] new nPlayerNum, nPlayerCount, nCurrentPlayer new sConnectNick[MAX_NAME_LEN] get_user_name(id, sConnectNick, MAX_NAME_LEN - 1) get_players(nPlayers, nPlayerNum, "c") set_hudmessage(000, 100, 255, get_pcvar_float(cvar_announce_alivepos_, get_pcvar_float(cvar_announce_alivepos_y), 0, 0.0, 10.0, 0.5, 0.10, 1) for (nPlayerCount = 1; nPlayerCount < nPlayerNum; nPlayerCount++) { nCurrentPlayer = nPlayers[nPlayerCount] client_print(nCurrentPlayer, print_chat, "%s: %L", PLUGIN_TAG, nCurrentPlayer, "MSG_REDIRECT_RECEIVE", sConnectNick, g_saServerNames[nSourceServer]) } } } new sID[1] sID[0] = id client_cmd(id, "setinfo ^"sredir^" ^"^"") client_cmd(id, "setinfo ^"password^" ^"^"") set_task(10.0, "reset_info", 0, sID, 1) } return PLUGIN_CONTINUE } public welcome_message(id[]) { new nID = id[0] new nLastServer = g_nLastServers[nID] if (nLastServer >= 0) { new sAnnounceText[MAX_MENUBODY_LEN] format(sAnnounceText, MAX_MENUBODY_LEN - 1, "%L", nID, "MSG_REDIRFROM", g_saServerNames[g_nOwnServer], g_saServerNames[nLastServer]) if ((get_pcvar_num(cvar_retry) == 1) && (get_pcvar_num(cvar_show) == 1)) format(sAnnounceText, MAX_MENUBODY_LEN - 1, "%s^n%L", sAnnounceText, nID, "MSG_RETRY_BACK_ANNOUNCE") set_hudmessage(000, 100, 255, -1.0, -1.0, 0, 0.0, 10.0, 0.5, 2.0, 1) show_hudmessage(nID, sAnnounceText) } } public client_putinserver(id) { new sID[1] sID[0] = id set_task(20.0, "welcome_message", 0, sID, 1) } #else public plugin_init() { log_amx("ERROR: Your AMXX version is too old for this plugin.") } #endif /* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE *{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1031\\ f0\\ fs16 \n\\ par } */ kura vieta te ir jaraksta servera nosaukms>?????plise help???? Link to comment Share on other sites More sharing options...
Ritsuki Posted March 19, 2008 Report Share Posted March 19, 2008 (edited) izlasi pamacibu, nevis uzdod stulbus jautajumus "amxmodx/config/serverlist.ini" tur raksti ar visu, taja pamaciba saita var visu izlasit soli pa solim, btw man ir tadi gluki kad katreiz kad serveris restartejas vinam pazud *redirect_active *redirect_auto *redirect_manual *redirect_follow taka sitie katreiz pa 0 ir kad serveris nokaras un restartejas, tad uz to laiku kamer kads neuzliek configu viniem atkal, tikmer redirect nestrada =/ kads nezin ka lai izdara lia default nava pa 0? EDITED: vairs nevajg es sma to editoju un vis k tagad Edited March 19, 2008 by Ritsuki Link to comment Share on other sites More sharing options...
harison555 Posted March 19, 2008 Report Share Posted March 19, 2008 (edited) lol tur tads serverlist.ini nemaz nau lunis tads!! Edited March 19, 2008 by harison555 Link to comment Share on other sites More sharing options...
DeimoN Posted March 19, 2008 Report Share Posted March 19, 2008 (edited) Gadiijumaa, kad pirmo reizi sleedz serveri iekshaa ar redirect pluginu tas fails briinumainaa kaartaa neparaadaas config mapee, luni ? btw. pats jau arii vinu tur var sataisiit.. Edited March 19, 2008 by DeimoN Link to comment Share on other sites More sharing options...
harison555 Posted March 19, 2008 Report Share Posted March 19, 2008 luni ? daunis!! bet eh neko!!! Link to comment Share on other sites More sharing options...
SadiS^CCCP* Posted May 16, 2008 Report Share Posted May 16, 2008 ;DDD psceec jusos paklausaas ganci ahuetj var ;DDD Link to comment Share on other sites More sharing options...
GOMA smile Posted May 16, 2008 Report Share Posted May 16, 2008 ir jabut serverlist.ini vai kautka ta jo kur tu rakstisi uz kadiem seeveriem lai parmet ? Link to comment Share on other sites More sharing options...
sLIDe Posted May 16, 2008 Report Share Posted May 16, 2008 serverlist.ini ir jāizveido pašiem. Iedošu vienu piemēru. Piemērs Link to comment Share on other sites More sharing options...
KukuliiC* Posted May 16, 2008 Report Share Posted May 16, 2008 Luk, varbut noderes mani server_redirect.rar Link to comment Share on other sites More sharing options...
Devil* Posted May 19, 2008 Report Share Posted May 19, 2008 :thumbsdown: Kaads latviski dabuut nevar??? Link to comment Share on other sites More sharing options...
deadlifter Posted May 19, 2008 Report Share Posted May 19, 2008 domaju tas ,kas vares atbildet ,lai liek ieksa visu instrukciju ka to gelu uzlikt jo to tik viegli nebija izdarit Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now