2004-08-28 05:30:23 +00:00
|
|
|
/* NetworkSyncServer.cpp
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "NetworkSyncServer.h"
|
2004-09-02 02:47:09 +00:00
|
|
|
#include "RageLog.h"
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
LanPlayer::LanPlayer() {
|
|
|
|
|
score = 0;
|
|
|
|
|
health = 0;
|
|
|
|
|
feet = 0;
|
|
|
|
|
projgrade = 0;
|
|
|
|
|
combo = 0;
|
2004-09-01 19:50:30 +00:00
|
|
|
currstep = 0;
|
2004-08-28 05:30:23 +00:00
|
|
|
maxCombo = 0;
|
|
|
|
|
Grade = 0;
|
|
|
|
|
offset = 0;
|
2004-09-06 04:24:51 +00:00
|
|
|
options = "";
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StepManiaLanServer::StepManiaLanServer() {
|
2004-08-29 03:31:01 +00:00
|
|
|
stop = true;
|
|
|
|
|
SecondSameSelect = false;
|
2004-08-29 20:36:37 +00:00
|
|
|
AssignPlayerIDs();
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StepManiaLanServer::~StepManiaLanServer() {
|
|
|
|
|
ServerStop();
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-28 13:41:22 +00:00
|
|
|
bool StepManiaLanServer::ServerStart() {
|
2004-08-28 05:30:23 +00:00
|
|
|
server.blocking = 0; /* Turn off blocking */
|
|
|
|
|
if (server.create())
|
|
|
|
|
if (server.bind(8765))
|
|
|
|
|
if (server.listen()) {
|
|
|
|
|
stop = false;
|
|
|
|
|
statsTime = time(NULL);
|
2004-08-28 13:41:22 +00:00
|
|
|
return true;
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
2004-08-28 13:41:22 +00:00
|
|
|
//Hopefully we will not get here. If we did, something went wrong above.
|
|
|
|
|
return false;
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::ServerStop() {
|
|
|
|
|
int x;
|
|
|
|
|
for (x = 0; x < NUMBERCLIENTS; x++) {
|
|
|
|
|
Client[x].clientSocket.close();
|
|
|
|
|
Client[x].Used = false;
|
|
|
|
|
}
|
|
|
|
|
server.close();
|
|
|
|
|
stop = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::ServerUpdate() {
|
|
|
|
|
if (!stop) {
|
|
|
|
|
NewClientCheck(); /* See if there is another client wanting to play */
|
|
|
|
|
UpdateClients();
|
2004-09-06 15:12:42 +00:00
|
|
|
// CheckReady();
|
2004-08-28 05:30:23 +00:00
|
|
|
if (time(NULL) > statsTime) {
|
|
|
|
|
SendStatsToClients();
|
|
|
|
|
statsTime = time(NULL);
|
|
|
|
|
}
|
|
|
|
|
// MoveClientToHost();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::UpdateClients() {
|
|
|
|
|
/* Go through all the clients and check to see if it is being used.
|
|
|
|
|
If so then try to get a backet and parse the data. */
|
|
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].Used == 1)
|
|
|
|
|
if (Client[x].GetData(Packet) >= 0)
|
|
|
|
|
ParseData(Packet, x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GameClient::GameClient() {
|
|
|
|
|
Used = 0;
|
2004-09-06 15:12:42 +00:00
|
|
|
GotStartRequest = 0;
|
2004-08-28 05:30:23 +00:00
|
|
|
clientSocket.blocking = 0;
|
|
|
|
|
twoPlayers = false;
|
|
|
|
|
version = 0;
|
|
|
|
|
startPosition = 0;
|
|
|
|
|
InGame = 0;
|
|
|
|
|
hasSong = false;
|
2004-09-06 15:12:42 +00:00
|
|
|
inNetMusicSelect = false;
|
|
|
|
|
isStarting = false; //Used for after ScreenNetMusicSelect but before InGame
|
2004-09-06 16:29:23 +00:00
|
|
|
wasIngame = false;
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GameClient::GetData(PacketFunctions &Packet) {
|
|
|
|
|
int length = -1;
|
2004-09-02 16:39:45 +00:00
|
|
|
CheckConnection();
|
2004-08-28 05:30:23 +00:00
|
|
|
Packet.ClearPacket();
|
|
|
|
|
length = clientSocket.ReadPack((char*)Packet.Data, NETMAXBUFFERSIZE);
|
|
|
|
|
return length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::ParseData(PacketFunctions &Packet, int clientNum) {
|
|
|
|
|
int command = Packet.Read1();
|
|
|
|
|
switch (command) {
|
|
|
|
|
case 0:
|
2004-09-02 16:39:45 +00:00
|
|
|
// No Operation
|
2004-08-28 05:30:23 +00:00
|
|
|
SendValue(129, clientNum);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
2004-09-02 16:39:45 +00:00
|
|
|
// No Operation response
|
2004-08-28 05:30:23 +00:00
|
|
|
break;
|
|
|
|
|
case 2:
|
2004-09-02 16:39:45 +00:00
|
|
|
// Hello
|
2004-08-28 05:30:23 +00:00
|
|
|
Hello(Packet, clientNum);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
2004-09-02 16:39:45 +00:00
|
|
|
// Start Request
|
2004-08-28 05:30:23 +00:00
|
|
|
Client[clientNum].StartRequest(Packet);
|
2004-09-06 15:12:42 +00:00
|
|
|
CheckReady();
|
2004-08-28 05:30:23 +00:00
|
|
|
break;
|
|
|
|
|
case 4:
|
2004-09-02 16:39:45 +00:00
|
|
|
// GameOver
|
2004-09-01 19:50:30 +00:00
|
|
|
GameOver(Packet, clientNum);
|
2004-08-28 05:30:23 +00:00
|
|
|
break;
|
|
|
|
|
case 5:
|
2004-09-02 16:39:45 +00:00
|
|
|
// StatsUpdate
|
2004-08-28 05:30:23 +00:00
|
|
|
Client[clientNum].UpdateStats(Packet);
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
2004-09-02 16:39:45 +00:00
|
|
|
// Style Update
|
2004-08-28 05:30:23 +00:00
|
|
|
Client[clientNum].StyleUpdate(Packet);
|
2004-08-29 20:36:37 +00:00
|
|
|
SendUserList();
|
2004-08-28 05:30:23 +00:00
|
|
|
break;
|
|
|
|
|
case 7:
|
2004-09-02 16:39:45 +00:00
|
|
|
// Chat message
|
2004-08-28 05:30:23 +00:00
|
|
|
RelayChat(Packet, clientNum);
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
SelectSong(Packet, clientNum);
|
|
|
|
|
break;
|
2004-09-06 15:12:42 +00:00
|
|
|
case 10:
|
|
|
|
|
ScreenNetMusicSelectStatus(Packet, clientNum);
|
|
|
|
|
break;
|
2004-09-06 04:24:51 +00:00
|
|
|
case 11:
|
|
|
|
|
Client[clientNum].Player[0].options = Packet.ReadNT();
|
|
|
|
|
Client[clientNum].Player[1].options = Packet.ReadNT();
|
|
|
|
|
break;
|
2004-08-28 05:30:23 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::Hello(PacketFunctions &Packet, int clientNum) {
|
|
|
|
|
int ClientVersion = Packet.Read1();
|
|
|
|
|
CString build = Packet.ReadNT();
|
|
|
|
|
|
|
|
|
|
Client[clientNum].SetClientVersion(ClientVersion, build);
|
|
|
|
|
|
2004-09-02 16:39:45 +00:00
|
|
|
Reply.ClearPacket();
|
2004-08-28 05:30:23 +00:00
|
|
|
Reply.Write1(130);
|
|
|
|
|
Reply.Write1(1);
|
|
|
|
|
Reply.WriteNT(servername);
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
SendNetPacket(clientNum, Reply);
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
if (ClientHost == -1)
|
|
|
|
|
ClientHost = clientNum;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameClient::StyleUpdate(PacketFunctions &Packet) {
|
|
|
|
|
int playernumber = 0;
|
2004-08-28 16:47:05 +00:00
|
|
|
Player[0].name = Player[1].name = "";
|
2004-08-28 05:30:23 +00:00
|
|
|
twoPlayers = Packet.Read1()-1;
|
|
|
|
|
for (int x = 0; x < twoPlayers+1; x++) {
|
|
|
|
|
playernumber = Packet.Read1();
|
|
|
|
|
Player[playernumber].name = Packet.ReadNT();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameClient::SetClientVersion(int ver, CString b) {
|
|
|
|
|
version = ver;
|
|
|
|
|
build = b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameClient::StartRequest(PacketFunctions &Packet) {
|
|
|
|
|
int firstbyte = Packet.Read1();
|
|
|
|
|
int secondbyte = Packet.Read1();
|
2004-09-01 19:50:30 +00:00
|
|
|
int thirdbyte = Packet.Read1();
|
2004-08-28 05:30:23 +00:00
|
|
|
Player[0].feet = firstbyte/16;
|
|
|
|
|
Player[1].feet = firstbyte%16;
|
|
|
|
|
|
|
|
|
|
if ((Player[0].feet > 0)&&(Player[1].feet > 0))
|
|
|
|
|
twoPlayers = true;
|
|
|
|
|
|
2004-09-01 19:50:30 +00:00
|
|
|
Player[0].diff = secondbyte/16;
|
|
|
|
|
Player[1].diff = secondbyte%16;
|
|
|
|
|
|
|
|
|
|
startPosition = thirdbyte/16;
|
2004-08-28 05:30:23 +00:00
|
|
|
gameInfo.title = Packet.ReadNT();
|
|
|
|
|
gameInfo.subtitle = Packet.ReadNT();
|
|
|
|
|
gameInfo.artist = Packet.ReadNT();
|
|
|
|
|
gameInfo.course = Packet.ReadNT();
|
|
|
|
|
|
2004-09-02 16:39:45 +00:00
|
|
|
for (int x = 0; x < 2; x++) {
|
|
|
|
|
Player[x].score = 0;
|
|
|
|
|
Player[x].combo = 0;
|
|
|
|
|
Player[x].projgrade = 0;
|
|
|
|
|
Player[x].maxCombo = 0;
|
2004-09-02 04:54:54 +00:00
|
|
|
|
2004-09-02 16:39:45 +00:00
|
|
|
memset((void*)Player[x].steps, 0, sizeof(int)*9);
|
2004-09-02 04:54:54 +00:00
|
|
|
}
|
2004-09-02 00:37:03 +00:00
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
GotStartRequest = true;
|
|
|
|
|
// InGame = true;
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::CheckReady() {
|
2004-09-06 15:12:42 +00:00
|
|
|
bool canStart = true;
|
2004-08-28 05:30:23 +00:00
|
|
|
int x;
|
2004-09-06 15:12:42 +00:00
|
|
|
|
|
|
|
|
//Only check clients that are starting (after ScreenNetMusicSelect before InGame).
|
|
|
|
|
for (x = 0; (x < NUMBERCLIENTS)&&(canStart == true); x++)
|
2004-08-28 05:30:23 +00:00
|
|
|
if (Client[x].Used == true)
|
2004-09-06 15:12:42 +00:00
|
|
|
if (Client[x].isStarting)
|
|
|
|
|
if (Client[x].GotStartRequest == false)
|
|
|
|
|
canStart = false;
|
2004-08-28 05:30:23 +00:00
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
if (canStart == true) {
|
2004-09-06 07:21:53 +00:00
|
|
|
//(Test this)
|
|
|
|
|
//For whatever reason we need to pause in a way
|
|
|
|
|
//that will not use a lot of CPU.
|
|
|
|
|
//When you try playing the music as soon as it's loaded
|
|
|
|
|
//it will not always play ... immediately
|
|
|
|
|
usleep ( 2000000 );
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
//Only start clients waiting for start between ScreenNetMusicSelect and game.
|
|
|
|
|
for (x = 0; x < NUMBERCLIENTS; x++) {
|
|
|
|
|
if (Client[x].Used == true)
|
|
|
|
|
if (Client[x].isStarting) {
|
|
|
|
|
Client[x].clientSocket.blocking = true;
|
|
|
|
|
SendValue(131, x);
|
|
|
|
|
Client[x].GotStartRequest = false;
|
|
|
|
|
if (Client[x].startPosition == 1) {
|
|
|
|
|
Client[x].isStarting = false;
|
|
|
|
|
Client[x].InGame = true;
|
|
|
|
|
//After we start the clients, clear each client's hasSong.
|
|
|
|
|
Client[x].hasSong = false;
|
|
|
|
|
}
|
|
|
|
|
Client[x].clientSocket.blocking = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-09-02 21:42:33 +00:00
|
|
|
}
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-09-01 19:50:30 +00:00
|
|
|
void StepManiaLanServer::GameOver(PacketFunctions &Packet, int clientNum) {
|
|
|
|
|
bool allOver = true;
|
2004-09-06 16:29:23 +00:00
|
|
|
int x;
|
2004-09-01 19:50:30 +00:00
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
Client[clientNum].GotStartRequest = false;
|
2004-09-01 19:50:30 +00:00
|
|
|
Client[clientNum].InGame = false;
|
2004-09-06 16:29:23 +00:00
|
|
|
Client[clientNum].wasIngame = true;
|
2004-09-06 15:12:42 +00:00
|
|
|
|
|
|
|
|
for (x = 0; (x < NUMBERCLIENTS)&&(allOver == true); x++)
|
2004-09-02 16:39:45 +00:00
|
|
|
if (Client[x].Used == true)
|
|
|
|
|
if ((Client[x].InGame == true))
|
2004-09-01 19:50:30 +00:00
|
|
|
allOver = false;
|
|
|
|
|
|
|
|
|
|
//Wait untill everyone is done before sending
|
|
|
|
|
if (allOver) {
|
|
|
|
|
numPlayers = SortStats(playersPtr);
|
|
|
|
|
Reply.ClearPacket();
|
2004-09-02 00:37:03 +00:00
|
|
|
Reply.Write1( 4+128 );
|
2004-09-02 21:05:57 +00:00
|
|
|
Reply.Write1( (uint8_t) numPlayers );
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-02 23:47:02 +00:00
|
|
|
Reply.Write1((uint8_t)playersPtr[x]->PlayerID);
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-01 19:50:30 +00:00
|
|
|
Reply.Write4(playersPtr[x]->score);
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-02 21:05:57 +00:00
|
|
|
Reply.Write1( (uint8_t) playersPtr[x]->projgrade );
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-02 21:05:57 +00:00
|
|
|
Reply.Write1( (uint8_t) playersPtr[x]->diff );
|
2004-09-02 04:54:54 +00:00
|
|
|
for (int y = 6; y >= 1; y--)
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-02 21:05:57 +00:00
|
|
|
Reply.Write2( (uint16_t) playersPtr[x]->steps[y] );
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-02 21:05:57 +00:00
|
|
|
Reply.Write2( (uint16_t) playersPtr[x]->steps[8] ); //Tack on OK
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-02 21:05:57 +00:00
|
|
|
Reply.Write2( (uint16_t) playersPtr[x]->maxCombo );
|
2004-09-06 15:12:42 +00:00
|
|
|
for (x = 0; x < numPlayers; x++)
|
2004-09-06 16:29:23 +00:00
|
|
|
Reply.WriteNT( playersPtr[x]->options );
|
2004-09-06 15:12:42 +00:00
|
|
|
|
|
|
|
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
2004-09-06 16:29:23 +00:00
|
|
|
if(Client[x].wasIngame)
|
2004-09-06 15:12:42 +00:00
|
|
|
SendNetPacket(x, Reply);
|
2004-09-06 16:29:23 +00:00
|
|
|
|
|
|
|
|
// SendToAllClients(Reply);
|
2004-09-01 19:50:30 +00:00
|
|
|
}
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
2004-08-29 20:36:37 +00:00
|
|
|
void StepManiaLanServer::AssignPlayerIDs() {
|
|
|
|
|
int counter = 0;
|
|
|
|
|
//Future: Figure out how to do dynamic numbering.
|
2004-09-02 16:39:45 +00:00
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
for(int y = 0; y < 2; y++)
|
|
|
|
|
Client[x].Player[y].PlayerID = counter++;
|
2004-08-29 20:36:37 +00:00
|
|
|
}
|
|
|
|
|
|
2004-08-28 05:30:23 +00:00
|
|
|
int StepManiaLanServer::SortStats(LanPlayer *playersPtr[]) {
|
|
|
|
|
int counter = 0;
|
|
|
|
|
LanPlayer *tmp;
|
|
|
|
|
StatsNameChange = false; //Set it to no name so stats will not send if there is not a change
|
|
|
|
|
bool allZero = true;
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
//Populate with in game players only
|
2004-08-28 05:30:23 +00:00
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
2004-09-02 16:39:45 +00:00
|
|
|
if (Client[x].Used == true)
|
2004-09-06 16:29:23 +00:00
|
|
|
if (Client[x].InGame||Client[x].wasIngame)
|
2004-09-06 15:12:42 +00:00
|
|
|
for (int y = 0; y < 2; y++)
|
|
|
|
|
if (Client[x].IsPlaying(y))
|
|
|
|
|
playersPtr[counter++] = &Client[x].Player[y];
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < counter; x++) {
|
|
|
|
|
//See if all the players have zero. Used to send names if everyone is 0
|
|
|
|
|
if ((playersPtr[x]->score > 0)&&(allZero == true))
|
|
|
|
|
allZero = false;
|
|
|
|
|
|
|
|
|
|
if ((x+1) < counter)
|
|
|
|
|
if ((playersPtr[x]->score) < (playersPtr[x+1]->score)) {
|
|
|
|
|
tmp = playersPtr[x];
|
|
|
|
|
playersPtr[x] = playersPtr[x+1];
|
|
|
|
|
playersPtr[x+1] = tmp;
|
|
|
|
|
x = 0;
|
|
|
|
|
StatsNameChange = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//If there are players all at 0, the name lsit won't be updated
|
|
|
|
|
//this make sure it is sent to the server eventually
|
|
|
|
|
if ((StatsNameChange == false)&&(allZero == true))
|
|
|
|
|
StatsNameChange = true;
|
|
|
|
|
|
|
|
|
|
return counter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::SendStatsToClients() {
|
2004-09-01 19:50:30 +00:00
|
|
|
int x;
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
numPlayers = SortStats(playersPtr); //Return number of players
|
|
|
|
|
|
|
|
|
|
//If there was a chagne in the name data, send it to the clients.
|
|
|
|
|
//Used to save bandwidth and some processing time.
|
|
|
|
|
if (StatsNameChange) {
|
|
|
|
|
|
|
|
|
|
/* Write and Send name packet */
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
Reply.Write1(133);
|
|
|
|
|
Reply.Write1(0);
|
2004-08-29 01:51:41 +00:00
|
|
|
Reply.Write1( (uint8_t) numPlayers );
|
2004-08-28 05:30:23 +00:00
|
|
|
StatsNameColumn(Reply, playersPtr, numPlayers);
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
//Send to in game clients only.
|
2004-08-28 05:30:23 +00:00
|
|
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].InGame == true)
|
2004-09-06 15:12:42 +00:00
|
|
|
SendNetPacket(x, Reply);
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write and send Combo packet */
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
|
|
|
|
|
Reply.Write1(133);
|
|
|
|
|
Reply.Write1(1);
|
2004-08-29 01:51:41 +00:00
|
|
|
Reply.Write1( (uint8_t) numPlayers );
|
2004-08-28 05:30:23 +00:00
|
|
|
StatsComboColumn(Reply, playersPtr, numPlayers);
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
//Send to in game clients only.
|
2004-08-28 05:30:23 +00:00
|
|
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].InGame == true)
|
2004-09-06 15:12:42 +00:00
|
|
|
SendNetPacket(x, Reply);
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Write and send projgrade packet*/
|
|
|
|
|
//Is it worth the programing troube to save a small amount of bandwidth here?
|
|
|
|
|
//Probably not. Sends all everytime unless developer feelings change.
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
|
|
|
|
|
Reply.Write1(133);
|
|
|
|
|
Reply.Write1(2);
|
2004-08-29 01:51:41 +00:00
|
|
|
Reply.Write1( (uint8_t) numPlayers );
|
2004-08-28 05:30:23 +00:00
|
|
|
StatsProjgradeColumn(Reply, playersPtr, numPlayers);
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
//Send to in game clients only.
|
2004-08-28 05:30:23 +00:00
|
|
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].InGame == true)
|
2004-09-06 15:12:42 +00:00
|
|
|
SendNetPacket(x, Reply);
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
void StepManiaLanServer::SendNetPacket(int client, PacketFunctions &Packet) {
|
2004-08-28 05:30:23 +00:00
|
|
|
/* If there is a connected client where we want to send then do so */
|
|
|
|
|
if (Client[client].Used == true)
|
2004-09-06 15:12:42 +00:00
|
|
|
Client[client].clientSocket.SendPack((char*)Packet.Data, Packet.Position);
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::StatsNameColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers) {
|
|
|
|
|
CString numname;
|
2004-08-29 20:36:37 +00:00
|
|
|
for (int x = 0; x < numPlayers; x++)
|
2004-09-02 21:05:57 +00:00
|
|
|
data.Write1( (uint8_t) playersPtr[x]->PlayerID );
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 16:39:45 +00:00
|
|
|
void StepManiaLanServer::StatsComboColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers) {
|
2004-08-29 01:51:41 +00:00
|
|
|
for( int x = 0; x < numPlayers; x++ )
|
2004-09-01 14:58:59 +00:00
|
|
|
data.Write2( (uint16_t) playersPtr[x]->combo);
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
2004-09-02 16:39:45 +00:00
|
|
|
void StepManiaLanServer::StatsProjgradeColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers) {
|
2004-08-29 01:51:41 +00:00
|
|
|
for( int x = 0; x < numPlayers; x++ )
|
|
|
|
|
data.Write1( (uint8_t) playersPtr[x]->projgrade );
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GameClient::IsPlaying(int x) {
|
|
|
|
|
/* If the feet setting is above 0, there must be a player. */
|
|
|
|
|
if (Player[x].feet > 0)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameClient::UpdateStats(PacketFunctions &Packet) {
|
|
|
|
|
/* Get the Stats form a packet */
|
|
|
|
|
char firstbyte = Packet.Read1();
|
|
|
|
|
char secondbyte = Packet.Read1();
|
|
|
|
|
int pID = int(firstbyte/16); /* MSN */
|
2004-09-02 16:39:45 +00:00
|
|
|
|
2004-09-01 19:50:30 +00:00
|
|
|
Player[pID].currstep = int(firstbyte%16); /* LSN */
|
2004-08-28 05:30:23 +00:00
|
|
|
Player[pID].projgrade = int(secondbyte/16);
|
|
|
|
|
Player[pID].score = Packet.Read4();
|
|
|
|
|
Player[pID].combo = Packet.Read2();
|
2004-09-02 16:39:45 +00:00
|
|
|
|
2004-08-28 05:30:23 +00:00
|
|
|
if (Player[pID].combo > Player[pID].maxCombo)
|
|
|
|
|
Player[pID].maxCombo = Player[pID].combo;
|
|
|
|
|
|
|
|
|
|
Player[pID].health = Packet.Read2();
|
|
|
|
|
Player[pID].offset = Packet.Read2();
|
2004-09-01 19:50:30 +00:00
|
|
|
Player[pID].steps[Player[pID].currstep]++;
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::NewClientCheck() {
|
|
|
|
|
/* Find the first available empty client. Then stick a new connection
|
|
|
|
|
in that client socket.*/
|
|
|
|
|
int CurrentEmptyClient = FindEmptyClient();
|
2004-09-02 16:39:45 +00:00
|
|
|
|
2004-08-28 05:30:23 +00:00
|
|
|
if (CurrentEmptyClient > -1)
|
2004-08-28 13:41:22 +00:00
|
|
|
if (server.accept(Client[CurrentEmptyClient].clientSocket) == 1)
|
2004-08-28 05:30:23 +00:00
|
|
|
Client[CurrentEmptyClient].Used = 1;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::SendValue(Uint8 value, int clientNum) {
|
|
|
|
|
Client[clientNum].clientSocket.SendPack((char*)&value, sizeof(Uint8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::RelayChat(PacketFunctions &Packet, int clientNum) {
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
CString message = "";
|
|
|
|
|
|
|
|
|
|
message += Client[clientNum].Player[0].name;
|
|
|
|
|
|
2004-08-28 16:47:05 +00:00
|
|
|
if (Client[clientNum].twoPlayers)
|
|
|
|
|
message += "&";
|
|
|
|
|
|
|
|
|
|
message += Client[clientNum].Player[1].name;
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
message += ": ";
|
|
|
|
|
message += Packet.ReadNT();
|
|
|
|
|
Reply.Write1(135);
|
|
|
|
|
Reply.WriteNT(message);
|
|
|
|
|
|
|
|
|
|
//Send to all clients
|
|
|
|
|
SendToAllClients(Reply);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::SelectSong(PacketFunctions &Packet, int clientNum) {
|
|
|
|
|
int use = Packet.Read1();
|
|
|
|
|
CString message;
|
|
|
|
|
|
|
|
|
|
if (use == 2) {
|
|
|
|
|
if (clientNum == 0) {
|
2004-08-29 03:31:01 +00:00
|
|
|
SecondSameSelect = false;
|
|
|
|
|
|
|
|
|
|
CurrentSongInfo.title = Packet.ReadNT();
|
|
|
|
|
CurrentSongInfo.artist = Packet.ReadNT();
|
|
|
|
|
CurrentSongInfo.subtitle = Packet.ReadNT();
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
Reply.Write1(136);
|
|
|
|
|
Reply.Write1(1);
|
2004-08-29 03:31:01 +00:00
|
|
|
Reply.WriteNT(CurrentSongInfo.title);
|
|
|
|
|
Reply.WriteNT(CurrentSongInfo.artist);
|
2004-09-02 16:39:45 +00:00
|
|
|
Reply.WriteNT(CurrentSongInfo.subtitle);
|
2004-08-28 05:30:23 +00:00
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
//Only send data to clients currently in ScreenNetMusicSelect
|
|
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].inNetMusicSelect)
|
|
|
|
|
SendNetPacket(x, Reply);
|
|
|
|
|
// SendToAllClients(Reply);
|
2004-08-29 03:31:01 +00:00
|
|
|
|
|
|
|
|
//The following code forces the host to select the same song twice in order to play it.
|
|
|
|
|
if (strcmp(CurrentSongInfo.title, LastSongInfo.title) == 0)
|
|
|
|
|
if (strcmp(CurrentSongInfo.artist, LastSongInfo.artist) == 0)
|
|
|
|
|
if (strcmp(CurrentSongInfo.artist, LastSongInfo.artist) == 0)
|
|
|
|
|
SecondSameSelect = true;
|
2004-09-02 16:39:45 +00:00
|
|
|
|
2004-08-29 03:31:01 +00:00
|
|
|
if (SecondSameSelect == false) {
|
|
|
|
|
LastSongInfo.title = CurrentSongInfo.title;
|
|
|
|
|
LastSongInfo.artist = CurrentSongInfo.artist;
|
|
|
|
|
LastSongInfo.subtitle = CurrentSongInfo.subtitle;
|
|
|
|
|
message = servername;
|
|
|
|
|
message += ":Play \"";
|
|
|
|
|
message += CurrentSongInfo.title;
|
|
|
|
|
message += "\"?";
|
|
|
|
|
ServerChat(message);
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-28 05:30:23 +00:00
|
|
|
} else {
|
|
|
|
|
message = servername;
|
|
|
|
|
message += ": You do not have permission to pick a song.";
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
Reply.Write1(135);
|
|
|
|
|
Reply.WriteNT(message);
|
2004-09-06 15:12:42 +00:00
|
|
|
SendNetPacket(clientNum, Reply);
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (use == 1) {
|
|
|
|
|
//If user dosn't have song
|
|
|
|
|
Client[clientNum].hasSong = false;
|
|
|
|
|
message = servername;
|
|
|
|
|
message += ": ";
|
|
|
|
|
message += Client[clientNum].Player[0].name;
|
|
|
|
|
|
|
|
|
|
if (Client[clientNum].twoPlayers) {
|
|
|
|
|
message += "&";
|
|
|
|
|
message += Client[clientNum].Player[1].name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
message += " lacks song \"";
|
2004-08-29 03:31:01 +00:00
|
|
|
message += CurrentSongInfo.title;
|
2004-08-28 05:30:23 +00:00
|
|
|
message += "\"";
|
|
|
|
|
ServerChat(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//If client has song
|
|
|
|
|
if (use == 0)
|
|
|
|
|
Client[clientNum].hasSong = true;
|
|
|
|
|
|
2004-08-29 03:31:01 +00:00
|
|
|
//Only play if everyone has the same song and the host has select the same song twice.
|
2004-09-02 04:54:54 +00:00
|
|
|
if ( CheckHasSongState() && SecondSameSelect && (clientNum == 0) ) {
|
2004-08-28 05:30:23 +00:00
|
|
|
Reply.ClearPacket();
|
|
|
|
|
Reply.Write1(136);
|
|
|
|
|
Reply.Write1(2);
|
2004-08-29 03:31:01 +00:00
|
|
|
Reply.WriteNT(CurrentSongInfo.title);
|
|
|
|
|
Reply.WriteNT(CurrentSongInfo.artist);
|
|
|
|
|
Reply.WriteNT(CurrentSongInfo.subtitle);
|
2004-09-02 16:39:45 +00:00
|
|
|
|
|
|
|
|
//Reset last song in case host picks same song again (otherwise dual select is bypassed)
|
2004-08-29 03:31:01 +00:00
|
|
|
LastSongInfo.title = "";
|
|
|
|
|
LastSongInfo.artist = "";
|
|
|
|
|
LastSongInfo.subtitle = "";
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
//Only send data to clients currently in ScreenNetMusicSelect
|
|
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].inNetMusicSelect) {
|
|
|
|
|
SendNetPacket(x, Reply);
|
|
|
|
|
//Designate the client is starting,
|
|
|
|
|
//after ScreenNetMusicSelect but before game play (InGame).
|
|
|
|
|
Client[x].isStarting = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SendToAllClients(Reply);
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool StepManiaLanServer::CheckHasSongState() {
|
|
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].Used == true)
|
2004-09-06 15:12:42 +00:00
|
|
|
if (Client[x].inNetMusicSelect)
|
|
|
|
|
if (Client[x].hasSong == false)
|
|
|
|
|
return false;
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::ClearHasSong() {
|
|
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].Used == true)
|
|
|
|
|
Client[x].hasSong = false;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::SendToAllClients(PacketFunctions &Packet) {
|
|
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
2004-09-06 15:12:42 +00:00
|
|
|
SendNetPacket(x, Packet);
|
2004-08-28 05:30:23 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
void StepManiaLanServer::ServerChat(CString message) {
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
Reply.Write1(135);
|
|
|
|
|
Reply.WriteNT(message);
|
|
|
|
|
SendToAllClients(Reply);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int StepManiaLanServer::FindEmptyClient() {
|
2004-09-02 16:39:45 +00:00
|
|
|
//Look at Used flag, if zero then it's an empty client (return client index, -1 if none).
|
2004-08-28 05:30:23 +00:00
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].Used == 0)
|
|
|
|
|
return x;
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameClient::CheckConnection() {
|
2004-09-02 16:39:45 +00:00
|
|
|
//If there is an error close the socket.
|
2004-08-28 05:30:23 +00:00
|
|
|
if (clientSocket.IsError()) {
|
|
|
|
|
clientSocket.close();
|
2004-09-06 15:12:42 +00:00
|
|
|
Used = GotStartRequest = hasSong = InGame = inNetMusicSelect = false;
|
2004-08-28 16:47:05 +00:00
|
|
|
Player[0].name = Player[1].name = "";
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StepManiaLanServer::MoveClientToHost() {
|
|
|
|
|
if (Client[ClientHost].Used == false)
|
|
|
|
|
for (int x = 1; x < NUMBERCLIENTS; x++)
|
|
|
|
|
if (Client[x].Used == true) {
|
|
|
|
|
ClientHost = x;
|
2004-09-02 16:39:45 +00:00
|
|
|
x = NUMBERCLIENTS+1;
|
2004-08-28 05:30:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-29 20:36:37 +00:00
|
|
|
void StepManiaLanServer::SendUserList() {
|
|
|
|
|
Reply.ClearPacket();
|
|
|
|
|
Reply.Write1(137);
|
|
|
|
|
Reply.Write1(NUMBERCLIENTS*2);
|
|
|
|
|
Reply.Write1(NUMBERCLIENTS*2);
|
2004-09-02 16:39:45 +00:00
|
|
|
|
2004-08-29 20:36:37 +00:00
|
|
|
for (int x = 0; x < NUMBERCLIENTS; x++) {
|
2004-09-02 16:39:45 +00:00
|
|
|
for (int y = 0; y < 2; y++) {
|
|
|
|
|
if (Client[x].Player[y].name.length() == 0) {
|
|
|
|
|
Reply.Write1(0);
|
|
|
|
|
} else {
|
|
|
|
|
Reply.Write1(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Reply.WriteNT(Client[x].Player[y].name);
|
2004-08-29 20:36:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
2004-09-02 16:39:45 +00:00
|
|
|
|
2004-08-29 20:36:37 +00:00
|
|
|
SendToAllClients(Reply);
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-06 15:12:42 +00:00
|
|
|
void StepManiaLanServer::ScreenNetMusicSelectStatus(PacketFunctions &Packet, int clientNum) {
|
|
|
|
|
LOG->Info("SNMS Change");
|
|
|
|
|
CString message = servername;
|
|
|
|
|
message += ": ";
|
|
|
|
|
if (Packet.Read1() == 1) {
|
|
|
|
|
Client[clientNum].inNetMusicSelect = true;
|
|
|
|
|
message += Client[clientNum].Player[0].name;
|
|
|
|
|
if (Client[clientNum].twoPlayers)
|
|
|
|
|
message += "&";
|
|
|
|
|
message += Client[clientNum].Player[1].name;
|
|
|
|
|
message += " entered the game.";
|
|
|
|
|
} else {
|
|
|
|
|
Client[clientNum].inNetMusicSelect = false;
|
|
|
|
|
message += Client[clientNum].Player[0].name;
|
|
|
|
|
if (Client[clientNum].twoPlayers)
|
|
|
|
|
message += "&";
|
|
|
|
|
message += Client[clientNum].Player[1].name;
|
|
|
|
|
message += " left the game.";
|
|
|
|
|
}
|
|
|
|
|
ServerChat(message);
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-28 05:30:23 +00:00
|
|
|
/*
|
|
|
|
|
* (c) 2003-2004 Joshua Allen
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
|
* distribute, and/or sell copies of the Software, and to permit persons to
|
|
|
|
|
* whom the Software is furnished to do so, provided that the above
|
|
|
|
|
* copyright notice(s) and this permission notice appear in all copies of
|
|
|
|
|
* the Software and that both the above copyright notice(s) and this
|
|
|
|
|
* permission notice appear in supporting documentation.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
|
|
|
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
|
|
|
|
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
|
|
|
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
|
|
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
|
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|