Integrated my SMLan server into Stepmania.
This commit is contained in:
@@ -252,8 +252,9 @@ FontManager.cpp FontManager.h GameSoundManager.cpp GameSoundManager.h GameManage
|
|||||||
GameState.cpp GameState.h InputFilter.cpp InputFilter.h \
|
GameState.cpp GameState.h InputFilter.cpp InputFilter.h \
|
||||||
InputMapper.cpp InputMapper.h InputQueue.cpp InputQueue.h LightsManager.cpp LightsManager.h \
|
InputMapper.cpp InputMapper.h InputQueue.cpp InputQueue.h LightsManager.cpp LightsManager.h \
|
||||||
MemoryCardManager.cpp MemoryCardManager.h NetworkSyncManager.cpp NetworkSyncManager.h \
|
MemoryCardManager.cpp MemoryCardManager.h NetworkSyncManager.cpp NetworkSyncManager.h \
|
||||||
NoteSkinManager.cpp NoteSkinManager.h PrefsManager.cpp PrefsManager.h ProfileManager.cpp ProfileManager.h \
|
NetworkSyncServer.cpp NetworkSyncServer.h NoteSkinManager.cpp NoteSkinManager.h \
|
||||||
ScreenManager.cpp ScreenManager.h SongManager.cpp SongManager.h ThemeManager.cpp ThemeManager.h \
|
PrefsManager.cpp PrefsManager.h ProfileManager.cpp ProfileManager.h ScreenManager.cpp \
|
||||||
|
ScreenManager.h SongManager.cpp SongManager.h ThemeManager.cpp ThemeManager.h \
|
||||||
UnlockSystem.cpp UnlockSystem.h
|
UnlockSystem.cpp UnlockSystem.h
|
||||||
|
|
||||||
if !WITHOUT_NETWORKING
|
if !WITHOUT_NETWORKING
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "NetworkSyncManager.h"
|
#include "NetworkSyncManager.h"
|
||||||
|
#include "NetworkSyncServer.h"
|
||||||
|
|
||||||
NetworkSyncManager *NSMAN;
|
NetworkSyncManager *NSMAN;
|
||||||
|
|
||||||
@@ -41,11 +42,21 @@ const ScreenMessage SM_ChangeSong = ScreenMessage(SM_User+5);
|
|||||||
|
|
||||||
NetworkSyncManager::NetworkSyncManager( LoadingWindow *ld )
|
NetworkSyncManager::NetworkSyncManager( LoadingWindow *ld )
|
||||||
{
|
{
|
||||||
ld->SetText("Initilizing Network...");
|
if( GetCommandlineArgument( "runserver" )) {
|
||||||
|
ld->SetText("Initilizing server...");
|
||||||
|
LANserver = new StepManiaLanServer;
|
||||||
|
isLanServer = true;
|
||||||
|
GetCommandlineArgument( "runserver", &LANserver->servername );
|
||||||
|
} else {
|
||||||
|
isLanServer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ld->SetText("Initilizing Client Network...");
|
||||||
NetPlayerClient = new EzSockets;
|
NetPlayerClient = new EzSockets;
|
||||||
NetPlayerClient->blocking = false;
|
NetPlayerClient->blocking = false;
|
||||||
m_ServerVersion = 0;
|
m_ServerVersion = 0;
|
||||||
|
|
||||||
|
|
||||||
useSMserver = false;
|
useSMserver = false;
|
||||||
m_startupStatus = 0; //By default, connection not tried.
|
m_startupStatus = 0; //By default, connection not tried.
|
||||||
|
|
||||||
@@ -58,6 +69,11 @@ NetworkSyncManager::~NetworkSyncManager ()
|
|||||||
if (useSMserver)
|
if (useSMserver)
|
||||||
NetPlayerClient->close();
|
NetPlayerClient->close();
|
||||||
delete NetPlayerClient;
|
delete NetPlayerClient;
|
||||||
|
|
||||||
|
if( isLanServer ) {
|
||||||
|
LANserver->ServerStop();
|
||||||
|
delete LANserver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkSyncManager::CloseConnection()
|
void NetworkSyncManager::CloseConnection()
|
||||||
@@ -111,11 +127,24 @@ void NetworkSyncManager::PostStartUp(CString ServerIP)
|
|||||||
//system, and not wait.
|
//system, and not wait.
|
||||||
|
|
||||||
bool dontExit = true;
|
bool dontExit = true;
|
||||||
|
|
||||||
|
//Don't block if the server is running
|
||||||
|
if( isLanServer ) {
|
||||||
|
NetPlayerClient->blocking = false;
|
||||||
|
} else {
|
||||||
NetPlayerClient->blocking = true;
|
NetPlayerClient->blocking = true;
|
||||||
|
}
|
||||||
|
|
||||||
//Following packet must get through, so we block for it.
|
//Following packet must get through, so we block for it.
|
||||||
|
//If we are serving we do not block for this.
|
||||||
NetPlayerClient->SendPack((char*)m_packet.Data,m_packet.Position);
|
NetPlayerClient->SendPack((char*)m_packet.Data,m_packet.Position);
|
||||||
|
|
||||||
|
//If we are serving, do this so we properly connect
|
||||||
|
//to the server.
|
||||||
|
if( isLanServer ) {
|
||||||
|
LANserver->ServerUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
m_packet.ClearPacket();
|
m_packet.ClearPacket();
|
||||||
|
|
||||||
while (dontExit)
|
while (dontExit)
|
||||||
@@ -128,6 +157,7 @@ void NetworkSyncManager::PostStartUp(CString ServerIP)
|
|||||||
//Only allow passing on handshake.
|
//Only allow passing on handshake.
|
||||||
//Otherwise scoreboard updates and such will confuse us.
|
//Otherwise scoreboard updates and such will confuse us.
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPlayerClient->blocking = false;
|
NetPlayerClient->blocking = false;
|
||||||
m_ServerVersion = m_packet.Read1();
|
m_ServerVersion = m_packet.Read1();
|
||||||
m_ServerName = m_packet.ReadNT();
|
m_ServerName = m_packet.ReadNT();
|
||||||
@@ -140,10 +170,15 @@ void NetworkSyncManager::StartUp()
|
|||||||
{
|
{
|
||||||
CString ServerIP;
|
CString ServerIP;
|
||||||
|
|
||||||
|
if( isLanServer ) {
|
||||||
|
LANserver->ServerStart();
|
||||||
|
}
|
||||||
|
|
||||||
if( GetCommandlineArgument( "netip", &ServerIP ) )
|
if( GetCommandlineArgument( "netip", &ServerIP ) )
|
||||||
PostStartUp(ServerIP);
|
PostStartUp(ServerIP);
|
||||||
else if( GetCommandlineArgument( "listen" ) )
|
else if( GetCommandlineArgument( "listen" ) )
|
||||||
PostStartUp("LISTEN");
|
PostStartUp("LISTEN");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -341,9 +376,16 @@ void NetworkSyncManager::StartRequest(short position)
|
|||||||
//way I know how to get precievably instantanious results
|
//way I know how to get precievably instantanious results
|
||||||
|
|
||||||
bool dontExit=true;
|
bool dontExit=true;
|
||||||
|
|
||||||
|
//Don't block if we are server.
|
||||||
|
if (isLanServer) {
|
||||||
|
NetPlayerClient->blocking=false;
|
||||||
|
} else {
|
||||||
NetPlayerClient->blocking=true;
|
NetPlayerClient->blocking=true;
|
||||||
|
}
|
||||||
|
|
||||||
//The following packet HAS to get through, so we turn blocking on for it as well
|
//The following packet HAS to get through, so we turn blocking on for it as well
|
||||||
|
//Don't block if we are serving
|
||||||
NetPlayerClient->SendPack((char*)&m_packet.Data, m_packet.Position);
|
NetPlayerClient->SendPack((char*)&m_packet.Data, m_packet.Position);
|
||||||
|
|
||||||
LOG->Trace("Waiting for RECV");
|
LOG->Trace("Waiting for RECV");
|
||||||
@@ -386,6 +428,10 @@ void NetworkSyncManager::DisplayStartupStatus()
|
|||||||
|
|
||||||
void NetworkSyncManager::Update(float fDeltaTime)
|
void NetworkSyncManager::Update(float fDeltaTime)
|
||||||
{
|
{
|
||||||
|
if (isLanServer) {
|
||||||
|
LANserver->ServerUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
if (useSMserver)
|
if (useSMserver)
|
||||||
ProcessInput();
|
ProcessInput();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#define NetworkSyncManager_H
|
#define NetworkSyncManager_H
|
||||||
|
|
||||||
#include "PlayerNumber.h"
|
#include "PlayerNumber.h"
|
||||||
|
|
||||||
class LoadingWindow;
|
class LoadingWindow;
|
||||||
|
|
||||||
const int NETPROTOCOLVERSION=1;
|
const int NETPROTOCOLVERSION=1;
|
||||||
@@ -19,6 +20,7 @@ enum NSScoreBoardColumn
|
|||||||
#define FOREACH_NSScoreBoardColumn( sc ) FOREACH_ENUM( NSScoreBoardColumn, NUM_NSSB_CATEGORIES, sc )
|
#define FOREACH_NSScoreBoardColumn( sc ) FOREACH_ENUM( NSScoreBoardColumn, NUM_NSSB_CATEGORIES, sc )
|
||||||
|
|
||||||
class EzSockets;
|
class EzSockets;
|
||||||
|
class StepManiaLanServer;
|
||||||
|
|
||||||
class PacketFunctions
|
class PacketFunctions
|
||||||
{
|
{
|
||||||
@@ -111,6 +113,9 @@ private:
|
|||||||
|
|
||||||
PacketFunctions m_packet;
|
PacketFunctions m_packet;
|
||||||
|
|
||||||
|
bool isLanServer;
|
||||||
|
StepManiaLanServer *LANserver;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,549 @@
|
|||||||
|
/* NetworkSyncServer.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NetworkSyncServer.h"
|
||||||
|
|
||||||
|
LanPlayer::LanPlayer() {
|
||||||
|
score = 0;
|
||||||
|
health = 0;
|
||||||
|
feet = 0;
|
||||||
|
projgrade = 0;
|
||||||
|
combo = 0;
|
||||||
|
step = 0;
|
||||||
|
maxCombo = 0;
|
||||||
|
Grade = 0;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
StepManiaLanServer::StepManiaLanServer() {
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StepManiaLanServer::~StepManiaLanServer() {
|
||||||
|
ServerStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::ServerStart() {
|
||||||
|
server.blocking = 0; /* Turn off blocking */
|
||||||
|
if (server.create())
|
||||||
|
if (server.bind(8765))
|
||||||
|
if (server.listen()) {
|
||||||
|
stop = false;
|
||||||
|
statsTime = time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
CheckReady();
|
||||||
|
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;
|
||||||
|
Ready = 0;
|
||||||
|
clientSocket.blocking = 0;
|
||||||
|
twoPlayers = false;
|
||||||
|
version = 0;
|
||||||
|
startPosition = 0;
|
||||||
|
InGame = 0;
|
||||||
|
hasSong = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameClient::GetData(PacketFunctions &Packet) {
|
||||||
|
int length = -1;
|
||||||
|
CheckConnection(); // Check for a connection problem
|
||||||
|
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:
|
||||||
|
/* No Operation */
|
||||||
|
SendValue(129, clientNum);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* No Operation response */
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* Hello */
|
||||||
|
Hello(Packet, clientNum);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
/* Start Request */
|
||||||
|
Client[clientNum].StartRequest(Packet);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
/* GameOver */
|
||||||
|
Client[clientNum].GameOver(Packet);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
/* StatsUpdate */
|
||||||
|
Client[clientNum].UpdateStats(Packet);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
/* Style Update */
|
||||||
|
Client[clientNum].StyleUpdate(Packet);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
// Chat message
|
||||||
|
RelayChat(Packet, clientNum);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
SelectSong(Packet, clientNum);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::Hello(PacketFunctions &Packet, int clientNum) {
|
||||||
|
Reply.ClearPacket();
|
||||||
|
|
||||||
|
int ClientVersion = Packet.Read1();
|
||||||
|
CString build = Packet.ReadNT();
|
||||||
|
|
||||||
|
Client[clientNum].SetClientVersion(ClientVersion, build);
|
||||||
|
|
||||||
|
Reply.Write1(130);
|
||||||
|
Reply.Write1(1);
|
||||||
|
Reply.WriteNT(servername);
|
||||||
|
|
||||||
|
SendNetPacket(clientNum, (char*)Reply.Data, Reply.Position);
|
||||||
|
|
||||||
|
if (ClientHost == -1)
|
||||||
|
ClientHost = clientNum;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameClient::StyleUpdate(PacketFunctions &Packet) {
|
||||||
|
int playernumber = 0;
|
||||||
|
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();
|
||||||
|
Player[0].feet = firstbyte/16;
|
||||||
|
Player[1].feet = firstbyte%16;
|
||||||
|
|
||||||
|
if ((Player[0].feet > 0)&&(Player[1].feet > 0))
|
||||||
|
twoPlayers = true;
|
||||||
|
|
||||||
|
startPosition = secondbyte/16;
|
||||||
|
gameInfo.title = Packet.ReadNT();
|
||||||
|
gameInfo.subtitle = Packet.ReadNT();
|
||||||
|
gameInfo.artist = Packet.ReadNT();
|
||||||
|
gameInfo.course = Packet.ReadNT();
|
||||||
|
|
||||||
|
cout << gameInfo.title << endl;
|
||||||
|
cout << gameInfo.subtitle << endl;
|
||||||
|
cout << gameInfo.artist << endl;
|
||||||
|
cout << gameInfo.course << endl;
|
||||||
|
|
||||||
|
Player[0].score = 0;
|
||||||
|
Player[0].combo = 0;
|
||||||
|
Player[0].projgrade = 0;
|
||||||
|
Player[1].score = 0;
|
||||||
|
Player[1].combo = 0;
|
||||||
|
Player[1].projgrade = 0;
|
||||||
|
|
||||||
|
Ready = true;
|
||||||
|
InGame = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::CheckReady() {
|
||||||
|
bool Start = true;
|
||||||
|
int x;
|
||||||
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Start == true)
|
||||||
|
if (Client[x].Used == true)
|
||||||
|
if (Client[x].Ready == false)
|
||||||
|
Start = false;
|
||||||
|
|
||||||
|
|
||||||
|
/* If All clients were ready, send the start command. */
|
||||||
|
if (Start == true)
|
||||||
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].Used == true) {
|
||||||
|
SendValue(131, x);
|
||||||
|
Client[x].Ready = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GameClient::GameOver(PacketFunctions &Packet) {
|
||||||
|
Ready = false;
|
||||||
|
InGame= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].Used == true) {
|
||||||
|
if (Client[x].IsPlaying(0)) {
|
||||||
|
playersPtr[counter] = &Client[x].Player[0];
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
if (Client[x].IsPlaying(1)) {
|
||||||
|
playersPtr[counter] = &Client[x].Player[1];
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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() {
|
||||||
|
// PacketFunctions StatsPacket;
|
||||||
|
int x, numPlayers;
|
||||||
|
|
||||||
|
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);
|
||||||
|
Reply.Write1(numPlayers);
|
||||||
|
StatsNameColumn(Reply, playersPtr, numPlayers);
|
||||||
|
|
||||||
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].InGame == true)
|
||||||
|
SendNetPacket(x, (char*)Reply.Data, Reply.Position);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write and send Combo packet */
|
||||||
|
Reply.ClearPacket();
|
||||||
|
|
||||||
|
Reply.Write1(133);
|
||||||
|
Reply.Write1(1);
|
||||||
|
Reply.Write1(numPlayers);
|
||||||
|
StatsComboColumn(Reply, playersPtr, numPlayers);
|
||||||
|
|
||||||
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].InGame == true)
|
||||||
|
SendNetPacket(x, (char*)Reply.Data, Reply.Position);
|
||||||
|
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
Reply.Write1(numPlayers);
|
||||||
|
StatsProjgradeColumn(Reply, playersPtr, numPlayers);
|
||||||
|
|
||||||
|
for (x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].InGame == true)
|
||||||
|
SendNetPacket(x, (char*)Reply.Data, Reply.Position);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::SendNetPacket(int client, char *data, int size) {
|
||||||
|
/* If there is a connected client where we want to send then do so */
|
||||||
|
if (Client[client].Used == true)
|
||||||
|
Client[client].clientSocket.SendPack(data, size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::StatsNameColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers) {
|
||||||
|
char number[9];
|
||||||
|
CString numname;
|
||||||
|
for (int x = 0; x < numPlayers; x++) {
|
||||||
|
sprintf(number, "%d", x+1);
|
||||||
|
numname = number;
|
||||||
|
numname += ". ";
|
||||||
|
numname += playersPtr[x]->name;
|
||||||
|
data.WriteNT(numname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::StatsComboColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers) {
|
||||||
|
for (int x = 0; x < numPlayers; x++)
|
||||||
|
data.Write2(playersPtr[x]->combo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::StatsProjgradeColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers) {
|
||||||
|
for (int x = 0; x < numPlayers; x++)
|
||||||
|
data.Write1(playersPtr[x]->projgrade);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
Player[pID].step = int(firstbyte%16); /* LSN */
|
||||||
|
Player[pID].projgrade = int(secondbyte/16);
|
||||||
|
Player[pID].score = Packet.Read4();
|
||||||
|
Player[pID].combo = Packet.Read2();
|
||||||
|
if (Player[pID].combo > Player[pID].maxCombo)
|
||||||
|
Player[pID].maxCombo = Player[pID].combo;
|
||||||
|
|
||||||
|
Player[pID].health = Packet.Read2();
|
||||||
|
Player[pID].offset = Packet.Read2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::NewClientCheck() {
|
||||||
|
/* Find the first available empty client. Then stick a new connection
|
||||||
|
in that client socket.*/
|
||||||
|
int CurrentEmptyClient = FindEmptyClient();
|
||||||
|
if (CurrentEmptyClient > -1)
|
||||||
|
if (server.accept(Client[CurrentEmptyClient].clientSocket) == 1) {
|
||||||
|
Client[CurrentEmptyClient].Used = 1;
|
||||||
|
cout << "Added client to " << CurrentEmptyClient << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (Client[clientNum].twoPlayers) {
|
||||||
|
message += "/";
|
||||||
|
message += Client[clientNum].Player[1].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
gameInfo.title = Packet.ReadNT();
|
||||||
|
gameInfo.artist = Packet.ReadNT();
|
||||||
|
gameInfo.subtitle = Packet.ReadNT();
|
||||||
|
|
||||||
|
Reply.ClearPacket();
|
||||||
|
Reply.Write1(136);
|
||||||
|
Reply.Write1(1);
|
||||||
|
Reply.WriteNT(gameInfo.title);
|
||||||
|
Reply.WriteNT(gameInfo.artist);
|
||||||
|
Reply.WriteNT(gameInfo.subtitle);
|
||||||
|
|
||||||
|
ClearHasSong();
|
||||||
|
|
||||||
|
SendToAllClients(Reply);
|
||||||
|
} else {
|
||||||
|
message = servername;
|
||||||
|
message += ": You do not have permission to pick a song.";
|
||||||
|
Reply.ClearPacket();
|
||||||
|
Reply.Write1(135);
|
||||||
|
Reply.WriteNT(message);
|
||||||
|
SendNetPacket(clientNum, (char*)Reply.Data, Reply.Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 \"";
|
||||||
|
message += gameInfo.title;
|
||||||
|
message += "\"";
|
||||||
|
ServerChat(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If client has song
|
||||||
|
if (use == 0)
|
||||||
|
Client[clientNum].hasSong = true;
|
||||||
|
|
||||||
|
if (CheckHasSongState()) {
|
||||||
|
Reply.ClearPacket();
|
||||||
|
Reply.Write1(136);
|
||||||
|
Reply.Write1(2);
|
||||||
|
Reply.WriteNT(gameInfo.title);
|
||||||
|
Reply.WriteNT(gameInfo.artist);
|
||||||
|
Reply.WriteNT(gameInfo.subtitle);
|
||||||
|
SendToAllClients(Reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StepManiaLanServer::CheckHasSongState() {
|
||||||
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].Used == true)
|
||||||
|
if (Client[x].hasSong == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
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++)
|
||||||
|
SendNetPacket(x, (char*)Packet.Data, Packet.Position);
|
||||||
|
|
||||||
|
}
|
||||||
|
void StepManiaLanServer::ServerChat(CString message) {
|
||||||
|
// PacketFunctions chat;
|
||||||
|
Reply.ClearPacket();
|
||||||
|
Reply.Write1(135);
|
||||||
|
Reply.WriteNT(message);
|
||||||
|
SendToAllClients(Reply);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int StepManiaLanServer::FindEmptyClient() {
|
||||||
|
/* Look at Used flag, if zero then it's an empty client.
|
||||||
|
Return the index. */
|
||||||
|
for (int x = 0; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].Used == 0)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameClient::CheckConnection() {
|
||||||
|
/* If there is an error close the socket. */
|
||||||
|
if (clientSocket.IsError()) {
|
||||||
|
clientSocket.close();
|
||||||
|
Used = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepManiaLanServer::MoveClientToHost() {
|
||||||
|
if (Client[ClientHost].Used == false)
|
||||||
|
for (int x = 1; x < NUMBERCLIENTS; x++)
|
||||||
|
if (Client[x].Used == true) {
|
||||||
|
ClientHost = x;
|
||||||
|
x = 17;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (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.
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
#ifndef NetworkSyncServer_H
|
||||||
|
#define NetworkSyncServer_H
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "ezsockets.h"
|
||||||
|
#include "NetworkSyncManager.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "StdString.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
typedef unsigned char Uint8;
|
||||||
|
|
||||||
|
#define NETMAXBUFFERSIZE 1020
|
||||||
|
#define NUMBERCLIENTS 16
|
||||||
|
|
||||||
|
class LanPlayer {
|
||||||
|
public:
|
||||||
|
string name;
|
||||||
|
long score;
|
||||||
|
int health;
|
||||||
|
int feet;
|
||||||
|
int projgrade;
|
||||||
|
int combo;
|
||||||
|
int step;
|
||||||
|
int maxCombo;
|
||||||
|
int Grade;
|
||||||
|
int offset;
|
||||||
|
LanPlayer();
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class GameInfo {
|
||||||
|
public:
|
||||||
|
CString title;
|
||||||
|
CString subtitle;
|
||||||
|
CString artist;
|
||||||
|
CString course;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class GameClient {
|
||||||
|
public:
|
||||||
|
bool Ready;
|
||||||
|
EzSockets clientSocket;
|
||||||
|
bool Used;
|
||||||
|
void UpdateStats(PacketFunctions &Packet);
|
||||||
|
void SetClientVersion(int ver, CString b);
|
||||||
|
void StartRequest(PacketFunctions &Packet);
|
||||||
|
int GetData(PacketFunctions &Packet);
|
||||||
|
void GameOver(PacketFunctions &Packet);
|
||||||
|
GameClient();
|
||||||
|
LanPlayer Player[2];
|
||||||
|
void CheckConnection();
|
||||||
|
bool IsPlaying(int Player);
|
||||||
|
void StyleUpdate(PacketFunctions &Packet);
|
||||||
|
bool InGame;
|
||||||
|
int twoPlayers;
|
||||||
|
bool hasSong;
|
||||||
|
private:
|
||||||
|
string build;
|
||||||
|
GameInfo gameInfo;
|
||||||
|
int version;
|
||||||
|
int startPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StepManiaLanServer {
|
||||||
|
public:
|
||||||
|
void ServerStart();
|
||||||
|
void ServerStop();
|
||||||
|
void ServerUpdate();
|
||||||
|
StepManiaLanServer();
|
||||||
|
~StepManiaLanServer();
|
||||||
|
CString servername;
|
||||||
|
private:
|
||||||
|
bool stop;
|
||||||
|
PacketFunctions Packet;
|
||||||
|
PacketFunctions Reply;
|
||||||
|
GameClient Client[NUMBERCLIENTS];
|
||||||
|
int CurrentEmptyClient;
|
||||||
|
EzSockets server;
|
||||||
|
int ClientHost;
|
||||||
|
LanPlayer *playersPtr[NUMBERCLIENTS*2];
|
||||||
|
time_t statsTime;
|
||||||
|
GameInfo gameInfo;
|
||||||
|
bool StatsNameChange;
|
||||||
|
|
||||||
|
void Hello(PacketFunctions&Packet, int clientNum);
|
||||||
|
void UpdateClients();
|
||||||
|
int FindEmptyClient();
|
||||||
|
void NewClientCheck();
|
||||||
|
void ParseData(PacketFunctions &Packet, int clientNum);
|
||||||
|
void SendValue(Uint8 value, int clientNum);
|
||||||
|
void CheckReady();
|
||||||
|
void MoveClientToHost();
|
||||||
|
void StatsComboColumn(PacketFunctions &data, LanPlayer *playersPtr[],
|
||||||
|
int numPlayers);
|
||||||
|
void SendStatsToClients();
|
||||||
|
void StatsProjgradeColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers);
|
||||||
|
void StatsNameColumn(PacketFunctions &data, LanPlayer *playersPtr[], int numPlayers);
|
||||||
|
void SendNetPacket(int client, char *data, int size);
|
||||||
|
int SortStats(LanPlayer *playersPtr[]);
|
||||||
|
void RelayChat(PacketFunctions &Packet, int clientNum);
|
||||||
|
void SelectSong(PacketFunctions &Packet, int clientNum);
|
||||||
|
void ServerChat(CString message);
|
||||||
|
void SendToAllClients(PacketFunctions &Packet);
|
||||||
|
bool CheckHasSongState();
|
||||||
|
void ClearHasSong();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (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.
|
||||||
|
*/
|
||||||
@@ -59,7 +59,7 @@ LINK32=link.exe
|
|||||||
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
|
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
|
||||||
# Begin Special Build Tool
|
# Begin Special Build Tool
|
||||||
IntDir=.\../Debug6
|
IntDir=.\../Debug6
|
||||||
TargetDir=\temp\stepmania\Program
|
TargetDir=\StepMania CVS\Program
|
||||||
TargetName=StepMania-debug
|
TargetName=StepMania-debug
|
||||||
SOURCE="$(InputPath)"
|
SOURCE="$(InputPath)"
|
||||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||||
@@ -96,7 +96,7 @@ LINK32=link.exe
|
|||||||
# SUBTRACT LINK32 /verbose /pdb:none /debug
|
# SUBTRACT LINK32 /verbose /pdb:none /debug
|
||||||
# Begin Special Build Tool
|
# Begin Special Build Tool
|
||||||
IntDir=.\../Release6
|
IntDir=.\../Release6
|
||||||
TargetDir=\temp\stepmania\Program
|
TargetDir=\StepMania CVS\Program
|
||||||
TargetName=StepMania
|
TargetName=StepMania
|
||||||
SOURCE="$(InputPath)"
|
SOURCE="$(InputPath)"
|
||||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||||
@@ -2959,6 +2959,14 @@ SOURCE=.\NetworkSyncManager.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\NetworkSyncServer.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\NetworkSyncServer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\NoteSkinManager.cpp
|
SOURCE=.\NoteSkinManager.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -2268,6 +2268,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
|||||||
<File
|
<File
|
||||||
RelativePath="NetworkSyncManager.h">
|
RelativePath="NetworkSyncManager.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="NetworkSyncServer.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="NetworkSyncServer.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="NoteSkinManager.cpp">
|
RelativePath="NoteSkinManager.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
Reference in New Issue
Block a user