400 lines
16 KiB
C++
400 lines
16 KiB
C++
// CashWorld Client Program
|
||
#include <cstdio>
|
||
#include <cstdlib>
|
||
#include <cstring>
|
||
#include <string>
|
||
#include <sstream>
|
||
#include <ctime>
|
||
#include "GSock/gsock.h"
|
||
#include "GSock/gsock_helper.h"
|
||
#include "ui_helper.h"
|
||
using namespace std;
|
||
|
||
const string SERVER_IP = "123.206.86.73";
|
||
const int PORT_CHECK = 59401;
|
||
const int PORT_LOGIN = 59402;
|
||
const int PORT_GAME = 59402;
|
||
|
||
char _xtime[256];
|
||
|
||
const char* _update_xtime()
|
||
{
|
||
time_t t = time(NULL);
|
||
strftime(_xtime, 256, "%Y-%m-%d %H:%M:%S", localtime(&t));
|
||
return _xtime;
|
||
}
|
||
|
||
FILE* _log_f = NULL;
|
||
#define xlog(fmt,...) _update_xtime();fprintf(_log_f,"<%s | %s> " fmt "\n",_xtime,__func__,##__VA_ARGS__);fflush(_log_f)
|
||
#define start_xlog() _log_f=fopen("log.txt","a");fprintf(_log_f,"==============================\n");fflush(_log_f)
|
||
|
||
std::string user_cert_code;
|
||
|
||
int update_check()
|
||
{
|
||
sock s;
|
||
if (s.connect(SERVER_IP, PORT_CHECK) < 0)
|
||
{
|
||
xlog("Cannot connect to server");
|
||
return -1;
|
||
}
|
||
sock_helper sh(s);
|
||
string response;
|
||
if (sh.sendline("get_current_version") <= 0 ||
|
||
sh.recvline(response)<0 )
|
||
{
|
||
xlog("Failed to querying version");
|
||
return -2;
|
||
}
|
||
istringstream istr(response);
|
||
string code, version;
|
||
if (!(istr >> code >> version))
|
||
{
|
||
xlog("Failed to parse version code. Response: %s", response.c_str());
|
||
return -3;
|
||
}
|
||
if (code != "current_version")
|
||
{
|
||
xlog("Wrong response header. Header: %s", code.c_str());
|
||
return -4;
|
||
}
|
||
|
||
xlog("Server response latest version is: %s", version.c_str());
|
||
return 0;
|
||
}
|
||
|
||
int user_login(const char* uname,const char* upass)
|
||
{
|
||
sock s;
|
||
if (s.connect(SERVER_IP, PORT_LOGIN) < 0)
|
||
{
|
||
xlog("Cannot connect to server");
|
||
return -1;
|
||
}
|
||
sock_helper sh(s);
|
||
|
||
if (sh.sendline("user_login") < 0 ||
|
||
sh.sendline(uname) < 0 ||
|
||
sh.sendline(upass) < 0)
|
||
{
|
||
xlog("Failed to send data");
|
||
return -2;
|
||
}
|
||
|
||
string response, code;
|
||
if (sh.recvline(response) <= 0 || sh.recvline(code) < 0)
|
||
{
|
||
xlog("Failed to recv data.");
|
||
return -3;
|
||
}
|
||
|
||
if (response != "login_ok")
|
||
{
|
||
xlog("Failed to login.");
|
||
return 1;
|
||
}
|
||
|
||
user_cert_code = code;
|
||
return 0;
|
||
}
|
||
|
||
void readline(char* outbuff, int size)
|
||
{
|
||
memset(outbuff, 0, size);
|
||
fgets(outbuff, size, stdin);
|
||
int sz = strlen(outbuff);
|
||
if (outbuff[sz - 1] == '\n') outbuff[sz - 1] = 0;
|
||
}
|
||
|
||
int ui_user_login()
|
||
{
|
||
while (true)
|
||
{
|
||
title("用户登录");
|
||
printf("用户名:"); fflush(stdout);
|
||
char uname[1024];
|
||
readline(uname, 1024);
|
||
printf("密码:"); fflush(stdout);
|
||
char upass[1024];
|
||
readline(upass, 1024);
|
||
|
||
title("用户登录");
|
||
printf("正在登录...\n");
|
||
int ret = user_login(uname, upass);
|
||
if (ret < 0)
|
||
{
|
||
printf("网络错误. 无法与服务器建立链接.\n");
|
||
return -1;
|
||
}
|
||
else if (ret > 0)
|
||
{
|
||
printf("用户名或密码错误. 请重试.\n");
|
||
WaitPause();
|
||
}
|
||
else return 0;
|
||
}
|
||
}
|
||
|
||
int do_get_my_profile(char* uname,int& cash)
|
||
{
|
||
sock s;
|
||
if (s.connect(SERVER_IP, PORT_GAME) < 0)
|
||
{
|
||
xlog("Cannot connect to server");
|
||
return -1;
|
||
}
|
||
sock_helper sh(s);
|
||
if (sh.sendline("get_my_profile") < 0 ||
|
||
sh.sendline(user_cert_code) < 0)
|
||
{
|
||
return -2;
|
||
}
|
||
string response;
|
||
if (sh.recvline(response) < 0)
|
||
{
|
||
return -3;
|
||
}
|
||
if (response != "my_profile_ok")
|
||
{
|
||
return -4;
|
||
}
|
||
string user_name;
|
||
string cash_str;
|
||
if (sh.recvline(user_name) <= 0 ||
|
||
sh.recvline(cash_str) < 0)
|
||
{
|
||
return -5;
|
||
}
|
||
|
||
strcpy(uname, user_name.c_str());
|
||
sscanf(cash_str.c_str(), "%d", &cash);
|
||
return 0;
|
||
}
|
||
|
||
void ui_view_my_profile()
|
||
{
|
||
title("个人资料");
|
||
printf("正在获取个人资料...\n");
|
||
|
||
char uname[1024] = { 0 };
|
||
int cash;
|
||
if (do_get_my_profile(uname, cash) < 0)
|
||
{
|
||
title("个人资料");
|
||
printf("无法获取个人资料.\n");
|
||
}
|
||
else
|
||
{
|
||
title("个人资料");
|
||
printf("用户名: %s\n", uname);
|
||
printf("金币数量: %d\n", cash);
|
||
}
|
||
|
||
WaitPause();
|
||
return;
|
||
}
|
||
|
||
int ui_game_guessnumber_input_gate(int& val)
|
||
{
|
||
title("猜数字-投入");
|
||
char uname[1024] = { 0 };
|
||
int cash = -1;
|
||
do_get_my_profile(uname, cash);
|
||
printf("尊敬的%s,您当前余额为%d元\n", uname, cash);
|
||
printf("请输入你要投入的金钱数量,留空返回.\n");
|
||
while (true)
|
||
{
|
||
char xbuf[1024] = { 0 };
|
||
|
||
readline(xbuf, 1024);
|
||
if (strlen(xbuf) < 1) return 0;
|
||
if (sscanf(xbuf, "%d", &val) != 1 || val < 1)
|
||
{
|
||
printf("请输入正确的投入金钱.\n");
|
||
ClearInput();
|
||
}
|
||
else break;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
int do_game_guessnumber(int val, int low, int high, int guess, int& result)
|
||
{
|
||
sock s;
|
||
if (s.connect(SERVER_IP, PORT_GAME) < 0)
|
||
{
|
||
xlog("Cannot connect to server");
|
||
return -1;
|
||
}
|
||
sock_helper sh(s);
|
||
|
||
char xbuf[1024] = { 0 };
|
||
sprintf(xbuf, "%d %d %d %d", val, low, high, guess);
|
||
|
||
if (sh.sendline("game_guess_number") < 0 ||
|
||
sh.sendline(user_cert_code) < 0 ||
|
||
sh.sendline(xbuf) < 0)
|
||
{
|
||
return -2;
|
||
}
|
||
|
||
string response;
|
||
string data;
|
||
if (sh.recvline(response) < 0)
|
||
{
|
||
return -3;
|
||
}
|
||
|
||
if (response != "guess_number_ok")
|
||
{
|
||
return -4;
|
||
}
|
||
|
||
if (sh.recvline(data) < 0)
|
||
{
|
||
return -5;
|
||
}
|
||
|
||
if (data == "guessed")
|
||
{
|
||
result = 1;
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
result = 0;
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void ui_game_guessnumber_classA()
|
||
{
|
||
int val;
|
||
if (ui_game_guessnumber_input_gate(val) == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
int c;
|
||
while (true)
|
||
{
|
||
title("猜数字");
|
||
printf("请输入你要猜的数字 (1-9):\n");
|
||
if (scanf("%d", &c) != 1 || c < 1 || c>9)
|
||
{
|
||
printf("请输入正确的数字.\n");
|
||
ClearInput();
|
||
}
|
||
else break;
|
||
}
|
||
|
||
int result;
|
||
if (do_game_guessnumber(val, 1, 9, c, result) < 0)
|
||
{
|
||
title("猜数字");
|
||
printf("网络异常.\n");
|
||
WaitPause();
|
||
return;
|
||
}
|
||
|
||
if (result)
|
||
{
|
||
title("猜数字");
|
||
printf("恭喜你猜中了!\n");
|
||
WaitPause();
|
||
}
|
||
else
|
||
{
|
||
title("猜数字");
|
||
printf("很抱歉,你没能猜中!\n");
|
||
WaitPause();
|
||
}
|
||
}
|
||
|
||
void ui_game_guessnumber_classB()
|
||
{
|
||
int val;
|
||
if (ui_game_guessnumber_input_gate(val) == 0)
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
void ui_game_guessnumber()
|
||
{
|
||
while (true)
|
||
{
|
||
title("猜数字");
|
||
printf("请选择难度, 难度越大奖励越丰厚.\n");
|
||
printf("[1] 中奖率10% 猜中奖励: 1.1\n[2] 中奖率1% 猜中奖励: 2.0\n[3] 返回\n");
|
||
int ss = GetChoice(3);
|
||
switch (ss)
|
||
{
|
||
case 1:
|
||
ui_game_guessnumber_classA();
|
||
break;
|
||
case 2:
|
||
ui_game_guessnumber_classB();
|
||
break;
|
||
case 3:
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
void ui_online_chat()
|
||
{
|
||
|
||
}
|
||
|
||
int ui_main_game()
|
||
{
|
||
while (true)
|
||
{
|
||
title("游戏大厅");
|
||
printf("[1] 查看资料\n[2] 开始游戏: 猜数字\n[3] 聊天室\n[4] 退出\n");
|
||
int ss = GetChoice(4);
|
||
switch (ss)
|
||
{
|
||
case 1:
|
||
ui_view_my_profile();
|
||
break;
|
||
case 2:
|
||
ui_game_guessnumber();
|
||
break;
|
||
case 3:
|
||
ui_online_chat();
|
||
break;
|
||
case 4:
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
int main()
|
||
{
|
||
start_xlog();
|
||
xlog("Program Started");
|
||
title("检查更新");
|
||
printf("检查更新中,请稍等...\n");
|
||
if (update_check() < 0)
|
||
{
|
||
printf("无法检查更新. 请查看你的网络连接.\n");
|
||
WaitPause();
|
||
//return 0;
|
||
}
|
||
if (ui_user_login() < 0)
|
||
{
|
||
xlog("Invalid return from user login");
|
||
return 0;
|
||
}
|
||
|
||
xlog("User logged in. Cert code: %s\n", user_cert_code.c_str());
|
||
|
||
ui_main_game();
|
||
|
||
xlog("Program Finished Successfully.");
|
||
return 0;
|
||
}
|
||
|