00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
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
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 }