RenRem.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Renegade remote server control utility *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/RenRem/RenRem.cpp $*
  25. * *
  26. * $Author:: Steve_t $*
  27. * *
  28. * $Modtime:: 8/23/02 11:06a $*
  29. * *
  30. * $Revision:: 6 $*
  31. * *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * *
  35. * *
  36. *---------------------------------------------------------------------------------------------*
  37. * *
  38. * Functions: *
  39. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  40. #include <winsock.h>
  41. #include <assert.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <conio.h>
  45. #include "servercontrol.h"
  46. #define RENREM_PORT 1234
  47. #define PROMPT ">"
  48. char CommandBuffer[16384];
  49. int BufferPos = 0;
  50. char RequestBuffer[512];
  51. bool GotResponse = false;
  52. bool Connected = false;
  53. bool DumpOutput = false;
  54. bool TruncateFile = true;
  55. unsigned long ResponseTime = 0;
  56. const char *App_Request_Callback(char *request)
  57. {
  58. cprintf(request);
  59. return("");
  60. }
  61. void App_Response_Callback(char *response)
  62. {
  63. cprintf(response);
  64. if (RequestBuffer[0] == 0) {
  65. cprintf(PROMPT);
  66. }
  67. BufferPos = 0;
  68. GotResponse = true;
  69. ResponseTime = timeGetTime();
  70. if (DumpOutput) {
  71. HANDLE file = INVALID_HANDLE_VALUE;
  72. if (TruncateFile) {
  73. file = CreateFile("RenRem.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  74. } else {
  75. file = CreateFile("RenRem.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  76. }
  77. TruncateFile = false;
  78. if (file != INVALID_HANDLE_VALUE) {
  79. SetFilePointer(file, 0, NULL, FILE_END);
  80. unsigned long actual = 0;
  81. WriteFile(file, response, strlen(response), &actual, NULL);
  82. CloseHandle(file);
  83. }
  84. }
  85. }
  86. int main(int argc, char **argv)
  87. {
  88. cprintf("Renegade Remote Server Management Tool\n");
  89. cprintf("Version 1.11 - ST 7/25/2002 3:20PM\n");
  90. cprintf("Usage: RenRem.exe <options> ip port password [local_port]\n\n");
  91. cprintf("Options: -r=Request - Send the specified request to the server then quit\n\n");
  92. if (argc < 2) {
  93. cprintf("Bad parameters\n");
  94. return(0);
  95. }
  96. int arg_offset = 0;
  97. unsigned long quit_after_time = 0;
  98. if ((strnicmp(argv[1], "-R=", 3) == 0) || (strnicmp(argv[1], "/R=", 3) == 0)) {
  99. strcpy(RequestBuffer, argv[1]);
  100. arg_offset++;
  101. quit_after_time = timeGetTime() + 3000;
  102. } else {
  103. RequestBuffer[0] = 0;
  104. }
  105. /*
  106. ** Must have at least 4 args.
  107. */
  108. if (argc < 4 + arg_offset) {
  109. cprintf("Bad parameters\n");
  110. return(0);
  111. }
  112. /*
  113. ** Get the IP.
  114. */
  115. unsigned long ip = inet_addr(argv[1+ arg_offset]);
  116. unsigned long port = atoi(argv[2 + arg_offset]);
  117. char *password = argv[3 + arg_offset];
  118. unsigned long local_port = RENREM_PORT;
  119. if (argc > (4 + arg_offset)) {
  120. local_port = atoi(argv[4 + arg_offset]);
  121. }
  122. if ((port & 0xffff0000) != 0 || port < 1024) {
  123. cprintf("Invalid port number %d\n", port);
  124. return(0);
  125. }
  126. if ((local_port & 0xffff0000) != 0 || port < 1024) {
  127. cprintf("Invalid local port number %d\n", port);
  128. return(0);
  129. }
  130. WSADATA wsa_data;
  131. if (WSAStartup(MAKEWORD(1,1), &wsa_data) != 0) {
  132. cprintf("WSAStartup failed: error code %d\n", GetLastError());
  133. return(0);
  134. }
  135. ServerControl.Allow_Remote_Admin(true);
  136. if (ServerControl.Start_Listening(local_port, password, &App_Request_Callback, &App_Response_Callback) == false) {
  137. cprintf("Failed to open socket for port %d\n", local_port);
  138. WSACleanup();
  139. return(0);
  140. }
  141. cprintf("RenRem online using port %d\n", local_port);
  142. cprintf("Entering console mode\n");
  143. cprintf("Type the remote management password to connect\n");
  144. cprintf("Press escape to quit\n");
  145. bool doit = true;
  146. int BufferPos = 1;
  147. sprintf(CommandBuffer, PROMPT);
  148. cprintf(PROMPT);
  149. /*
  150. ** If a initial request is to be made then connect automatically.
  151. */
  152. if (RequestBuffer[0] != 0) {
  153. Connected = false;
  154. GotResponse = false;
  155. ServerControl.Send_Message(password, ip, port);
  156. }
  157. while (doit) {
  158. Sleep(1);
  159. ServerControl.Service();
  160. if (_kbhit()) {
  161. int input = _getche();
  162. if (input == 27) {
  163. cprintf("\nQuitting\n");
  164. break;
  165. }
  166. switch (input) {
  167. /*
  168. ** TAB key used to get command line suggestions in the game. Here we just print spaces, so jump back to the start
  169. ** of the line so it at least matches what's in the buffer.
  170. */
  171. case 9:
  172. BufferPos = 1;
  173. cprintf("\r\n");
  174. cprintf(PROMPT);
  175. break;
  176. case 13:
  177. if (BufferPos > 1) {
  178. CommandBuffer[BufferPos] = 0;
  179. /*
  180. ** Verify quit command.
  181. */
  182. bool send = true;
  183. if (stricmp(&CommandBuffer[1], "quit") == 0) {
  184. cprintf("\r\n Press 'Y' to shutdown server...");
  185. int key = _getch();
  186. if ((key & 0xff) != 'Y' && (key & 0xff) != 'y') {
  187. send = false;
  188. }
  189. }
  190. if (send) {
  191. ServerControl.Send_Message(&CommandBuffer[1], ip, port);
  192. TruncateFile = true;
  193. }
  194. }
  195. BufferPos = 1;
  196. cprintf("\r\n");
  197. cprintf(PROMPT);
  198. ServerControl.Service();
  199. break;
  200. /*
  201. ** Backspace.
  202. */
  203. case 8:
  204. if (BufferPos > 1) {
  205. BufferPos--;
  206. cprintf(" \b");
  207. } else {
  208. /*
  209. ** Compensate for backspace going too far.
  210. */
  211. if (BufferPos == 1) {
  212. cprintf(PROMPT);
  213. }
  214. }
  215. break;
  216. default:
  217. if (input == 32 || isgraph(input)) {
  218. CommandBuffer[BufferPos++] = (input & 0xff);
  219. }
  220. break;
  221. }
  222. }
  223. if (RequestBuffer[0] != 0 && GotResponse) {
  224. if (!Connected) {
  225. /*
  226. ** Must be connection response - send specified request now.
  227. */
  228. Connected = true;
  229. GotResponse = false;
  230. DumpOutput = true;
  231. ServerControl.Send_Message(&RequestBuffer[3], ip, port);
  232. } else {
  233. /*
  234. ** Must be request response - we are done.
  235. */
  236. if (quit_after_time && ResponseTime && timeGetTime() - ResponseTime > 600) {
  237. break;
  238. }
  239. }
  240. }
  241. if (quit_after_time && (timeGetTime() > quit_after_time)) {
  242. break;
  243. }
  244. }
  245. WSACleanup();
  246. return(0);
  247. }