1/***************************************************************************
2* KBlocks, a falling blocks game for KDE *
3* Copyright (C) 2010 Zhongjie Cai <squall.leonhart.cai@gmail.com> *
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 2 of the License, or *
8* (at your option) any later version. *
9***************************************************************************/
10#include "KBlocksNetPlayer.h"
11
12#include "AI/KBlocksAILog.h"
13
14KBlocksNetPlayer::KBlocksNetPlayer(GamePlayerInterface * player, const string& serverIP, int localPort)
15{
16 mpNetClient = new KBlocksNetClient(serverIP.c_str(), localPort);
17
18 mpPlayer = player;
19
20 mActionList.clear();
21}
22
23KBlocksNetPlayer::~KBlocksNetPlayer()
24{
25 delete mpNetClient;
26}
27
28void KBlocksNetPlayer::joinGame(int gameIndex)
29{
30 int tmpByteCount = 0;
31 char tmpByteData[256];
32 string tmpName = mpPlayer->getName();
33
34 tmpByteData[tmpByteCount++] = '|';
35 tmpByteData[tmpByteCount++] = 'a';
36 tmpByteData[tmpByteCount++] = 'p';
37 tmpByteData[tmpByteCount++] = '|';
38 tmpByteData[tmpByteCount++] = (char)gameIndex + '0';
39 tmpByteData[tmpByteCount++] = '|';
40 for(size_t i = 0; i < tmpName.length(); ++i)
41 {
42 tmpByteData[tmpByteCount++] = (char)tmpName[i];
43 }
44 tmpByteData[tmpByteCount++] = 0;
45
46 mpNetClient->sendData(tmpByteCount, tmpByteData);
47}
48
49void KBlocksNetPlayer::quitGame()
50{
51 char tmpByteData[5] = {'|', 'd', 'p', '|', '\0'};
52 mpNetClient->sendData(5, tmpByteData);
53}
54
55void KBlocksNetPlayer::startGame(KBlocksSingleGame * p)
56{
57 char tmpByteData[4] = {'|', 's', '|', '\0'};
58 mpNetClient->sendData(4, tmpByteData);
59
60 mpGame = p;
61 mpPlayer->startGame(mpGame);
62
63 mActionList.clear();
64}
65
66void KBlocksNetPlayer::stopGame()
67{
68 char tmpByteData[4] = {'|', 'c', '|', '\0'};
69 mpNetClient->sendData(4, tmpByteData);
70
71 mpPlayer->stopGame();
72 mpGame = 0;
73
74 mActionList.clear();
75}
76
77bool KBlocksNetPlayer::execute()
78{
79 bool execResult = true;
80 char* tmpByteData = new char[256];
81
82 int ret = mpNetClient->recvData(256, tmpByteData);
83 if (ret < 0)
84 {
85 // Do nothing...
86 //printf("--Nothing received\n");
87 }
88 else if (tmpByteData[0] == -1)
89 {
90 mSendLength = (unsigned char)tmpByteData[1];
91 //printf("--Send Length = %d\n", mSendLength);
92 }
93 else if (tmpByteData[0] == 127)
94 {
95 execResult = false;
96 //printf("--Game Ended\n");
97 }
98 else
99 {
100 //printf("++Game Updates (%d) of [%d bytes]\n", (int)tmpByteData[0], ret);
101 int tmpPieceCount = formIntFromByte(tmpByteData + 13);
102 for (int i = 0; i < tmpPieceCount; ++i)
103 {
104 mpGame->getPiece(i)->decodeData((unsigned char*)tmpByteData + 17 + i * 4);
105 }
106
107 mpGame->getField()->decodeData((unsigned char*)tmpByteData + 18 + tmpPieceCount * 4);
108
109 mActionList.clear();
110 mpPlayer->think(&mActionList);
111
112 GamePlayer_ActionList::iterator it;
113 int byteCounter = 0;
114 char* tmpSendData = new char[256];
115 tmpSendData[byteCounter++] = '|';
116 tmpSendData[byteCounter++] = 'r';
117 tmpSendData[byteCounter++] = 'p';
118 tmpSendData[byteCounter++] = '|';
119 if (mSendLength == 0)
120 {
121 for(it = mActionList.begin(); it != mActionList.end(); it++)
122 {
123 tmpSendData[byteCounter++] = (char)*it + '0';
124 }
125 }
126 else if (!mActionList.empty())
127 {
128 for(int i = 0; i < mSendLength; i++)
129 {
130 tmpSendData[byteCounter++] = (char)mActionList.front() + '0';
131 mActionList.pop_front();
132 if (mActionList.empty())
133 {
134 break;
135 }
136 }
137 }
138 tmpSendData[byteCounter++] = '|';
139 tmpSendData[byteCounter++] = '\0';
140
141 mpNetClient->sendData(byteCounter, tmpSendData);
142 //printf("Sending : [%s]\n", tmpSendData);
143
144 delete [] tmpSendData;
145 }
146
147 delete [] tmpByteData;
148
149 return execResult;
150}
151
152int KBlocksNetPlayer::formIntFromByte(char * data)
153{
154 int value = 0;
155 value += ((int)data[0]) & 0x000000FF;
156 value += (((int)data[1]) << 8) & 0x0000FF00;
157 value += (((int)data[2]) << 16) & 0x00FF0000;
158 value += (((int)data[3]) << 24) & 0xFF000000;
159 return value;
160}
161