mp_callbacks.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 #include "../client.h"
00027 #include "../cl_team.h"
00028 #include "../ui/ui_main.h"
00029 #include "../ui/ui_popup.h"
00030 #include "mp_callbacks.h"
00031 #include "mp_serverlist.h"
00032 #include "mp_team.h"
00033 
00034 teamData_t teamData;
00035 static cvar_t *rcon_client_password;
00036 static cvar_t *rcon_address;
00037 static cvar_t *info_password;
00038 
00039 void CL_Connect_f (void)
00040 {
00041     char server[MAX_VAR];
00042     char serverport[16];
00043 
00044     if (!selectedServer && Cmd_Argc() != 2 && Cmd_Argc() != 3) {
00045         Com_Printf("Usage: %s <server> [<port>]\n", Cmd_Argv(0));
00046         return;
00047     }
00048 
00049     if (Cmd_Argc() == 2) {
00050         Q_strncpyz(server, Cmd_Argv(1), sizeof(server));
00051         Q_strncpyz(serverport, DOUBLEQUOTE(PORT_SERVER), sizeof(serverport));
00052     } else if (Cmd_Argc() == 3) {
00053         Q_strncpyz(server, Cmd_Argv(1), sizeof(server));
00054         Q_strncpyz(serverport, Cmd_Argv(2), sizeof(serverport));
00055     } else {
00056         assert(selectedServer);
00057         Q_strncpyz(server, selectedServer->node, sizeof(server));
00058         Q_strncpyz(serverport, selectedServer->service, sizeof(serverport));
00059     }
00060 
00061     if (!chrDisplayList.num && !MP_LoadDefaultTeamMultiplayer()) {
00062         UI_Popup(_("Error"), _("Assemble a team first"));
00063         return;
00064     }
00065 
00066     if (Cvar_GetInteger("mn_server_need_password")) {
00067         UI_PushWindow("serverpassword", NULL);
00068         return;
00069     }
00070 
00071     /* if running a local server, kill it and reissue */
00072     SV_Shutdown("Server quit.", qfalse);
00073     CL_Disconnect();
00074 
00075     Q_strncpyz(cls.servername, server, sizeof(cls.servername));
00076     Q_strncpyz(cls.serverport, serverport, sizeof(cls.serverport));
00077 
00078     CL_SetClientState(ca_connecting);
00079 
00080     UI_InitStack(NULL, "multiplayerInGame", qfalse, qfalse);
00081 }
00082 
00083 static void CL_RconCallback (struct net_stream *s)
00084 {
00085     struct dbuffer *buf = NET_ReadMsg(s);
00086     if (buf) {
00087         const int cmd = NET_ReadByte(buf);
00088         char str[8];
00089         NET_ReadStringLine(buf, str, sizeof(str));
00090 
00091         if (cmd == clc_oob && !strcmp(str, "print")) {
00092             char str[2048];
00093             NET_ReadString(buf, str, sizeof(str));
00094             Com_Printf("%s\n", str);
00095         }
00096     }
00097     NET_StreamFree(s);
00098 }
00099 
00104 void CL_Rcon_f (void)
00105 {
00106     char message[MAX_STRING_CHARS];
00107 
00108     if (Cmd_Argc() < 2) {
00109         Com_Printf("Usage: %s <command>\n", Cmd_Argv(0));
00110         return;
00111     }
00112 
00113     if (!rcon_client_password->string) {
00114         Com_Printf("You must set 'rcon_password' before issuing an rcon command.\n");
00115         return;
00116     }
00117 
00118     Com_sprintf(message, sizeof(message), "rcon %s %s",
00119         rcon_client_password->string, Cmd_Args());
00120 
00121     if (cls.state >= ca_connected) {
00122         NET_OOB_Printf(cls.netStream, "%s", message);
00123     } else if (rcon_address->string) {
00124         const char *port;
00125         struct net_stream *s;
00126 
00127         if (strstr(rcon_address->string, ":"))
00128             port = strstr(rcon_address->string, ":") + 1;
00129         else
00130             port = DOUBLEQUOTE(PORT_SERVER);
00131 
00132         s = NET_Connect(rcon_address->string, port);
00133         if (s) {
00134             NET_OOB_Printf(s, "%s", message);
00135             NET_StreamSetCallback(s, &CL_RconCallback);
00136         }
00137     } else {
00138         Com_Printf("You are not connected to any server\n");
00139     }
00140 }
00141 
00148 void CL_Disconnect_f (void)
00149 {
00150     SV_ShutdownWhenEmpty();
00151     CL_Drop();
00152 }
00153 
00157 void CL_Reconnect_f (void)
00158 {
00159     if (Com_ServerState())
00160         return;
00161 
00162     if (cls.servername[0]) {
00163         if (cls.state >= ca_connecting) {
00164             Com_Printf("disconnecting...\n");
00165             CL_Disconnect();
00166         }
00167 
00168         cls.connectTime = CL_Milliseconds() - 1500;
00169 
00170         CL_SetClientState(ca_connecting);
00171         Com_Printf("reconnecting...\n");
00172     } else
00173         Com_Printf("No server to reconnect to\n");
00174 }
00175 
00181 static void CL_SelectTeam_Init_f (void)
00182 {
00183     /* reset menu text */
00184     UI_ResetData(TEXT_STANDARD);
00185 
00186     if (Com_ServerState())
00187         Cvar_Set("cl_admin", "1");
00188     else
00189         Cvar_Set("cl_admin", "0");
00190 
00191     NET_OOB_Printf(cls.netStream, "teaminfo %i", PROTOCOL_VERSION);
00192     UI_RegisterText(TEXT_STANDARD, _("Select a free team or your coop team"));
00193 }
00194 
00199 static void CL_TeamNum_f (void)
00200 {
00201     int i = cl_teamnum->integer;
00202     static char buf[MAX_STRING_CHARS];
00203 
00204     cl_teamnum->modified = qfalse;
00205 
00206     if (i <= TEAM_CIVILIAN || i > teamData.maxteams) {
00207         Cvar_SetValue("cl_teamnum", TEAM_DEFAULT);
00208         i = TEAM_DEFAULT;
00209     }
00210 
00211     if (strncmp(Cmd_Argv(0), "teamnum_dec", 11)) {
00212         for (i--; i > TEAM_CIVILIAN; i--) {
00213             if (teamData.maxPlayersPerTeam > teamData.teamCount[i]) {
00214                 Cvar_SetValue("cl_teamnum", i);
00215                 Com_sprintf(buf, sizeof(buf), _("Current team: %i"), i);
00216                 UI_RegisterText(TEXT_STANDARD, buf);
00217                 break;
00218             } else {
00219                 UI_RegisterText(TEXT_STANDARD, _("Team is already in use"));
00220                 Com_DPrintf(DEBUG_CLIENT, "team %i is already in use: %i (max: %i)\n",
00221                     i, teamData.teamCount[i], teamData.maxPlayersPerTeam);
00222             }
00223         }
00224     } else {
00225         for (i++; i <= teamData.maxteams; i++) {
00226             if (teamData.maxPlayersPerTeam > teamData.teamCount[i]) {
00227                 Cvar_SetValue("cl_teamnum", i);
00228                 Com_sprintf(buf, sizeof(buf), _("Current team: %i"), i);
00229                 UI_RegisterText(TEXT_STANDARD, buf);
00230                 break;
00231             } else {
00232                 UI_RegisterText(TEXT_STANDARD, _("Team is already in use"));
00233                 Com_DPrintf(DEBUG_CLIENT, "team %i is already in use: %i (max: %i)\n",
00234                     i, teamData.teamCount[i], teamData.maxPlayersPerTeam);
00235             }
00236         }
00237     }
00238 
00239 #if 0
00240     if (!teamnum->modified)
00241         UI_RegisterText(TEXT_STANDARD, _("Invalid or full team"));
00242 #endif
00243     CL_SelectTeam_Init_f();
00244 }
00245 
00251 static int CL_CompleteNetworkAddress (const char *partial, const char **match)
00252 {
00253     int i, matches = 0;
00254     const char *localMatch[MAX_COMPLETE];
00255     const size_t len = strlen(partial);
00256     if (!len) {
00257         /* list them all if there was no parameter given */
00258         for (i = 0; i < MAX_BOOKMARKS; i++) {
00259             const char *adrStr = Cvar_GetString(va("adr%i", i));
00260             if (adrStr[0] != '\0')
00261                 Com_Printf("%s\n", adrStr);
00262         }
00263         return 0;
00264     }
00265 
00266     localMatch[matches] = NULL;
00267 
00268     /* search all matches and fill the localMatch array */
00269     for (i = 0; i < MAX_BOOKMARKS; i++) {
00270         const char *adrStr = Cvar_GetString(va("adr%i", i));
00271         if (adrStr[0] != '\0' && !strncmp(partial, adrStr, len)) {
00272             Com_Printf("%s\n", adrStr);
00273             localMatch[matches++] = adrStr;
00274             if (matches >= MAX_COMPLETE)
00275                 break;
00276         }
00277     }
00278 
00279     return Cmd_GenericCompleteFunction(len, match, matches, localMatch);
00280 }
00281 
00282 void MP_CallbacksInit (void)
00283 {
00284     rcon_client_password = Cvar_Get("rcon_password", "", 0, "Remote console password");
00285     rcon_address = Cvar_Get("rcon_address", "", 0, "Address of the host you would like to control via rcon");
00286     info_password = Cvar_Get("password", "", CVAR_USERINFO, NULL);
00287     Cmd_AddCommand("mp_selectteam_init", CL_SelectTeam_Init_f, "Function that gets all connected players and let you choose a free team");
00288     Cmd_AddCommand("teamnum_dec", CL_TeamNum_f, "Decrease the prefered teamnum");
00289     Cmd_AddCommand("teamnum_inc", CL_TeamNum_f, "Increase the prefered teamnum");
00290     Cmd_AddCommand("saveteam", MP_SaveTeamMultiplayer_f, "Save a multiplayer team slot");
00291     Cmd_AddCommand("loadteam", MP_LoadTeamMultiplayer_f, "Load a multiplayer team slot");
00292     Cmd_AddCommand("team_comments", MP_MultiplayerTeamSlotComments_f, "Fills the multiplayer team selection menu with the team names");
00293     Cmd_AddCommand("mp_team_update", MP_UpdateMenuParameters_f, "");
00294     Cmd_AddCommand("mp_team_select", MP_TeamSelect_f, "");
00295     Cmd_AddCommand("pingservers", CL_PingServers_f, "Ping all servers in local network to get the serverlist");
00296     Cmd_AddCommand("disconnect", CL_Disconnect_f, "Disconnect from the current server");
00297     Cmd_AddCommand("connect", CL_Connect_f, "Connect to given ip");
00298     Cmd_AddParamCompleteFunction("connect", CL_CompleteNetworkAddress);
00299     Cmd_AddCommand("reconnect", CL_Reconnect_f, "Reconnect to last server");
00300     Cmd_AddCommand("rcon", CL_Rcon_f, "Execute a rcon command - see rcon_password");
00301     Cmd_AddParamCompleteFunction("rcon", CL_CompleteNetworkAddress);
00302     Cmd_AddCommand("mp_toggleactor", MP_ToggleActorForTeam_f, NULL);
00303     Cmd_AddCommand("mp_saveteamstate", MP_SaveTeamState_f, NULL);
00304     Cmd_AddCommand("mp_autoteam", MP_AutoTeam_f, "Assign initial multiplayer equipment to soldiers");
00305 }
00306 
00307 void MP_CallbacksShutdown (void)
00308 {
00309     Cmd_RemoveCommand("mp_selectteam_init");
00310     Cmd_RemoveCommand("teamnum_dec");
00311     Cmd_RemoveCommand("teamnum_inc");
00312     Cmd_RemoveCommand("saveteam");
00313     Cmd_RemoveCommand("loadteam");
00314     Cmd_RemoveCommand("team_comments");
00315     Cmd_RemoveCommand("mp_team_update");
00316     Cmd_RemoveCommand("mp_team_select");
00317     Cmd_RemoveCommand("rcon");
00318     Cmd_RemoveCommand("pingservers");
00319     Cmd_RemoveCommand("disconnect");
00320     Cmd_RemoveCommand("connect");
00321     Cmd_RemoveCommand("reconnect");
00322     Cmd_RemoveCommand("mp_toggleactor");
00323     Cmd_RemoveCommand("mp_saveteamstate");
00324     Cmd_RemoveCommand("mp_autoteam");
00325 }

Generated by  doxygen 1.6.2