Protocol command 10 added. SendNetPacket change. CheckReady not only deals with

clients wanting to start a game.  Game over now only sends stats to clients that were
 in game.  Stats sorting of and sending to in game clients.  SongSelect only sends
 data to clients currently in ScreenNetMusicSelect.
This commit is contained in:
Josh Allen
2004-09-06 15:12:42 +00:00
parent fa356decdf
commit 633f22b748
2 changed files with 120 additions and 55 deletions
+112 -51
View File
@@ -55,7 +55,7 @@ void StepManiaLanServer::ServerUpdate() {
if (!stop) { if (!stop) {
NewClientCheck(); /* See if there is another client wanting to play */ NewClientCheck(); /* See if there is another client wanting to play */
UpdateClients(); UpdateClients();
CheckReady(); // CheckReady();
if (time(NULL) > statsTime) { if (time(NULL) > statsTime) {
SendStatsToClients(); SendStatsToClients();
statsTime = time(NULL); statsTime = time(NULL);
@@ -75,13 +75,15 @@ void StepManiaLanServer::UpdateClients() {
GameClient::GameClient() { GameClient::GameClient() {
Used = 0; Used = 0;
Ready = 0; GotStartRequest = 0;
clientSocket.blocking = 0; clientSocket.blocking = 0;
twoPlayers = false; twoPlayers = false;
version = 0; version = 0;
startPosition = 0; startPosition = 0;
InGame = 0; InGame = 0;
hasSong = false; hasSong = false;
inNetMusicSelect = false;
isStarting = false; //Used for after ScreenNetMusicSelect but before InGame
} }
int GameClient::GetData(PacketFunctions &Packet) { int GameClient::GetData(PacketFunctions &Packet) {
@@ -109,6 +111,7 @@ void StepManiaLanServer::ParseData(PacketFunctions &Packet, int clientNum) {
case 3: case 3:
// Start Request // Start Request
Client[clientNum].StartRequest(Packet); Client[clientNum].StartRequest(Packet);
CheckReady();
break; break;
case 4: case 4:
// GameOver // GameOver
@@ -130,6 +133,9 @@ void StepManiaLanServer::ParseData(PacketFunctions &Packet, int clientNum) {
case 8: case 8:
SelectSong(Packet, clientNum); SelectSong(Packet, clientNum);
break; break;
case 10:
ScreenNetMusicSelectStatus(Packet, clientNum);
break;
case 11: case 11:
Client[clientNum].Player[0].options = Packet.ReadNT(); Client[clientNum].Player[0].options = Packet.ReadNT();
Client[clientNum].Player[1].options = Packet.ReadNT(); Client[clientNum].Player[1].options = Packet.ReadNT();
@@ -150,7 +156,7 @@ void StepManiaLanServer::Hello(PacketFunctions &Packet, int clientNum) {
Reply.Write1(1); Reply.Write1(1);
Reply.WriteNT(servername); Reply.WriteNT(servername);
SendNetPacket(clientNum, (char*)Reply.Data, Reply.Position); SendNetPacket(clientNum, Reply);
if (ClientHost == -1) if (ClientHost == -1)
ClientHost = clientNum; ClientHost = clientNum;
@@ -200,50 +206,58 @@ void GameClient::StartRequest(PacketFunctions &Packet) {
memset((void*)Player[x].steps, 0, sizeof(int)*9); memset((void*)Player[x].steps, 0, sizeof(int)*9);
} }
Ready = true; GotStartRequest = true;
InGame = true; // InGame = true;
} }
void StepManiaLanServer::CheckReady() { void StepManiaLanServer::CheckReady() {
bool Start = true; bool canStart = true;
int x; int x;
for (x = 0; x < NUMBERCLIENTS; x++)
if (Start == true) //Only check clients that are starting (after ScreenNetMusicSelect before InGame).
for (x = 0; (x < NUMBERCLIENTS)&&(canStart == true); x++)
if (Client[x].Used == true) if (Client[x].Used == true)
if (Client[x].Ready == false) if (Client[x].isStarting)
Start = false; if (Client[x].GotStartRequest == false)
canStart = false;
if (canStart == true) {
// If All clients were ready, send the start command
if (Start == true) {
//(Test this) //(Test this)
//For whatever reason we need to pause in a way //For whatever reason we need to pause in a way
//that will not use a lot of CPU. //that will not use a lot of CPU.
//When you try playing the music as soon as it's loaded //When you try playing the music as soon as it's loaded
//it will not always play ... immediately //it will not always play ... immediately
for (x = 0; x < NUMBERCLIENTS; x++)
Client[x].clientSocket.blocking = true;
usleep ( 2000000 ); usleep ( 2000000 );
for (x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].Used == true) {
SendValue(131, x);
Client[x].Ready = false;
}
for (x = 0; x < NUMBERCLIENTS; x++)
Client[x].clientSocket.blocking = false;
//After we start the clients, clear each client's hasSong. //Only start clients waiting for start between ScreenNetMusicSelect and game.
ClearHasSong(); 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;
}
}
} }
} }
void StepManiaLanServer::GameOver(PacketFunctions &Packet, int clientNum) { void StepManiaLanServer::GameOver(PacketFunctions &Packet, int clientNum) {
bool allOver = true; bool allOver = true;
int x = 0;
Client[clientNum].Ready = false; Client[clientNum].GotStartRequest = false;
Client[clientNum].InGame = false; Client[clientNum].InGame = false;
for (int x = 0; (x < NUMBERCLIENTS)&&(allOver == true); x++)
//Only check clients in game
for (x = 0; (x < NUMBERCLIENTS)&&(allOver == true); x++)
if (Client[x].Used == true) if (Client[x].Used == true)
if ((Client[x].InGame == true)) if ((Client[x].InGame == true))
allOver = false; allOver = false;
@@ -254,24 +268,30 @@ void StepManiaLanServer::GameOver(PacketFunctions &Packet, int clientNum) {
Reply.ClearPacket(); Reply.ClearPacket();
Reply.Write1( 4+128 ); Reply.Write1( 4+128 );
Reply.Write1( (uint8_t) numPlayers ); Reply.Write1( (uint8_t) numPlayers );
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.Write1((uint8_t)playersPtr[x]->PlayerID); Reply.Write1((uint8_t)playersPtr[x]->PlayerID);
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.Write4(playersPtr[x]->score); Reply.Write4(playersPtr[x]->score);
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.Write1( (uint8_t) playersPtr[x]->projgrade ); Reply.Write1( (uint8_t) playersPtr[x]->projgrade );
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.Write1( (uint8_t) playersPtr[x]->diff ); Reply.Write1( (uint8_t) playersPtr[x]->diff );
for (int y = 6; y >= 1; y--) for (int y = 6; y >= 1; y--)
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.Write2( (uint16_t) playersPtr[x]->steps[y] ); Reply.Write2( (uint16_t) playersPtr[x]->steps[y] );
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.Write2( (uint16_t) playersPtr[x]->steps[8] ); //Tack on OK Reply.Write2( (uint16_t) playersPtr[x]->steps[8] ); //Tack on OK
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.Write2( (uint16_t) playersPtr[x]->maxCombo ); Reply.Write2( (uint16_t) playersPtr[x]->maxCombo );
for (int x = 0; x < numPlayers; x++) for (x = 0; x < numPlayers; x++)
Reply.WriteNT( playersPtr[x]->options ); Reply.WriteNT( playersPtr[x]->options );
SendToAllClients(Reply);
//Only send stats to clients that were in game
for (x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].InGame) {
SendNetPacket(x, Reply);
Client[x].InGame = false;
}
} }
} }
@@ -289,11 +309,13 @@ int StepManiaLanServer::SortStats(LanPlayer *playersPtr[]) {
StatsNameChange = false; //Set it to no name so stats will not send if there is not a change StatsNameChange = false; //Set it to no name so stats will not send if there is not a change
bool allZero = true; bool allZero = true;
//Populate with in game players only
for (int x = 0; x < NUMBERCLIENTS; x++) for (int x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].Used == true) if (Client[x].Used == true)
for (int y = 0; y < 2; y++) if (Client[x].InGame)
if (Client[x].IsPlaying(y)) for (int y = 0; y < 2; y++)
playersPtr[counter++] = &Client[x].Player[y]; if (Client[x].IsPlaying(y))
playersPtr[counter++] = &Client[x].Player[y];
for (int x = 0; x < counter; x++) { for (int x = 0; x < counter; x++) {
@@ -335,9 +357,10 @@ void StepManiaLanServer::SendStatsToClients() {
Reply.Write1( (uint8_t) numPlayers ); Reply.Write1( (uint8_t) numPlayers );
StatsNameColumn(Reply, playersPtr, numPlayers); StatsNameColumn(Reply, playersPtr, numPlayers);
//Send to in game clients only.
for (x = 0; x < NUMBERCLIENTS; x++) for (x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].InGame == true) if (Client[x].InGame == true)
SendNetPacket(x, (char*)Reply.Data, Reply.Position); SendNetPacket(x, Reply);
} }
@@ -349,9 +372,10 @@ void StepManiaLanServer::SendStatsToClients() {
Reply.Write1( (uint8_t) numPlayers ); Reply.Write1( (uint8_t) numPlayers );
StatsComboColumn(Reply, playersPtr, numPlayers); StatsComboColumn(Reply, playersPtr, numPlayers);
//Send to in game clients only.
for (x = 0; x < NUMBERCLIENTS; x++) for (x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].InGame == true) if (Client[x].InGame == true)
SendNetPacket(x, (char*)Reply.Data, Reply.Position); SendNetPacket(x, Reply);
/* Write and send projgrade packet*/ /* Write and send projgrade packet*/
@@ -364,16 +388,17 @@ void StepManiaLanServer::SendStatsToClients() {
Reply.Write1( (uint8_t) numPlayers ); Reply.Write1( (uint8_t) numPlayers );
StatsProjgradeColumn(Reply, playersPtr, numPlayers); StatsProjgradeColumn(Reply, playersPtr, numPlayers);
//Send to in game clients only.
for (x = 0; x < NUMBERCLIENTS; x++) for (x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].InGame == true) if (Client[x].InGame == true)
SendNetPacket(x, (char*)Reply.Data, Reply.Position); SendNetPacket(x, Reply);
} }
void StepManiaLanServer::SendNetPacket(int client, char *data, int size) { void StepManiaLanServer::SendNetPacket(int client, PacketFunctions &Packet) {
/* If there is a connected client where we want to send then do so */ /* If there is a connected client where we want to send then do so */
if (Client[client].Used == true) if (Client[client].Used == true)
Client[client].clientSocket.SendPack(data, size); Client[client].clientSocket.SendPack((char*)Packet.Data, Packet.Position);
} }
@@ -474,7 +499,11 @@ void StepManiaLanServer::SelectSong(PacketFunctions &Packet, int clientNum) {
Reply.WriteNT(CurrentSongInfo.artist); Reply.WriteNT(CurrentSongInfo.artist);
Reply.WriteNT(CurrentSongInfo.subtitle); Reply.WriteNT(CurrentSongInfo.subtitle);
SendToAllClients(Reply); //Only send data to clients currently in ScreenNetMusicSelect
for (int x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].inNetMusicSelect)
SendNetPacket(x, Reply);
// SendToAllClients(Reply);
//The following code forces the host to select the same song twice in order to play it. //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.title, LastSongInfo.title) == 0)
@@ -499,7 +528,7 @@ void StepManiaLanServer::SelectSong(PacketFunctions &Packet, int clientNum) {
Reply.ClearPacket(); Reply.ClearPacket();
Reply.Write1(135); Reply.Write1(135);
Reply.WriteNT(message); Reply.WriteNT(message);
SendNetPacket(clientNum, (char*)Reply.Data, Reply.Position); SendNetPacket(clientNum, Reply);
} }
} }
@@ -539,15 +568,25 @@ void StepManiaLanServer::SelectSong(PacketFunctions &Packet, int clientNum) {
LastSongInfo.artist = ""; LastSongInfo.artist = "";
LastSongInfo.subtitle = ""; LastSongInfo.subtitle = "";
SendToAllClients(Reply); //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);
} }
} }
bool StepManiaLanServer::CheckHasSongState() { bool StepManiaLanServer::CheckHasSongState() {
for (int x = 0; x < NUMBERCLIENTS; x++) for (int x = 0; x < NUMBERCLIENTS; x++)
if (Client[x].Used == true) if (Client[x].Used == true)
if (Client[x].hasSong == false) if (Client[x].inNetMusicSelect)
return false; if (Client[x].hasSong == false)
return false;
return true; return true;
} }
@@ -561,7 +600,7 @@ void StepManiaLanServer::ClearHasSong() {
void StepManiaLanServer::SendToAllClients(PacketFunctions &Packet) { void StepManiaLanServer::SendToAllClients(PacketFunctions &Packet) {
for (int x = 0; x < NUMBERCLIENTS; x++) for (int x = 0; x < NUMBERCLIENTS; x++)
SendNetPacket(x, (char*)Packet.Data, Packet.Position); SendNetPacket(x, Packet);
} }
void StepManiaLanServer::ServerChat(CString message) { void StepManiaLanServer::ServerChat(CString message) {
@@ -584,7 +623,7 @@ void GameClient::CheckConnection() {
//If there is an error close the socket. //If there is an error close the socket.
if (clientSocket.IsError()) { if (clientSocket.IsError()) {
clientSocket.close(); clientSocket.close();
Used = Ready = hasSong = InGame = false; Used = GotStartRequest = hasSong = InGame = inNetMusicSelect = false;
Player[0].name = Player[1].name = ""; Player[0].name = Player[1].name = "";
} }
} }
@@ -619,6 +658,28 @@ void StepManiaLanServer::SendUserList() {
SendToAllClients(Reply); SendToAllClients(Reply);
} }
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);
}
/* /*
* (c) 2003-2004 Joshua Allen * (c) 2003-2004 Joshua Allen
* All rights reserved. * All rights reserved.
+7 -3
View File
@@ -47,7 +47,7 @@ class GameInfo {
class GameClient { class GameClient {
public: public:
bool Ready; bool GotStartRequest;
EzSockets clientSocket; EzSockets clientSocket;
bool Used; bool Used;
void UpdateStats(PacketFunctions &Packet); void UpdateStats(PacketFunctions &Packet);
@@ -62,11 +62,14 @@ class GameClient {
bool InGame; bool InGame;
int twoPlayers; int twoPlayers;
bool hasSong; bool hasSong;
bool inNetMusicSelect;
int startPosition;
bool isStarting;
private: private:
string build; string build;
GameInfo gameInfo; GameInfo gameInfo;
int version; int version;
int startPosition;
}; };
class StepManiaLanServer { class StepManiaLanServer {
@@ -106,7 +109,7 @@ class StepManiaLanServer {
void SendStatsToClients(); void SendStatsToClients();
void StatsProjgradeColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers); void StatsProjgradeColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers);
void StatsNameColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers); void StatsNameColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers);
void SendNetPacket(int client, char *data, int size); void SendNetPacket(int client, PacketFunctions &Packet);
int SortStats(LanPlayer *playersPtr[]); int SortStats(LanPlayer *playersPtr[]);
void RelayChat(PacketFunctions &Packet, int clientNum); void RelayChat(PacketFunctions &Packet, int clientNum);
void SelectSong(PacketFunctions &Packet, int clientNum); void SelectSong(PacketFunctions &Packet, int clientNum);
@@ -117,6 +120,7 @@ class StepManiaLanServer {
void AssignPlayerIDs(); void AssignPlayerIDs();
void SendUserList(); void SendUserList();
void GameOver(PacketFunctions &Packet, int clientNum); void GameOver(PacketFunctions &Packet, int clientNum);
void ScreenNetMusicSelectStatus(PacketFunctions &Packet, int clientNum);
}; };
#endif #endif