These are the files necessiary for making the network work.
This commit is contained in:
@@ -0,0 +1,116 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Class: Network Sync Manager
|
||||||
|
|
||||||
|
Desc: See Header.
|
||||||
|
|
||||||
|
Copyright (c) 2003-2004 by the person(s) listed below. All rights reserved.
|
||||||
|
Charles Lohr
|
||||||
|
Joshua Allen
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "global.h"
|
||||||
|
#include "NetworkSyncManager.h"
|
||||||
|
#include "ezsockets.h"
|
||||||
|
#include "RageLog.h"
|
||||||
|
|
||||||
|
|
||||||
|
NetworkSyncManager::NetworkSyncManager ()
|
||||||
|
{
|
||||||
|
//No Code
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkSyncManager::~NetworkSyncManager ()
|
||||||
|
{
|
||||||
|
if (useSMserver!=1)
|
||||||
|
return ;
|
||||||
|
//Close Connection to server nicely.
|
||||||
|
NetPlayerClient.close();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetworkSyncManager::Connect(char * addy, int port)
|
||||||
|
{
|
||||||
|
if (port!=8765)
|
||||||
|
return (-1);
|
||||||
|
//Make sure using port 8765
|
||||||
|
//This may change in future versions
|
||||||
|
//It is this way now for protocol's purpose.
|
||||||
|
//If there is a new protocol developed down the road
|
||||||
|
|
||||||
|
//Since under non-lan conditions, the client
|
||||||
|
//will be connecting to localhost, this port does not matter.
|
||||||
|
|
||||||
|
|
||||||
|
NetPlayerClient.create(); //Initilize Socket
|
||||||
|
|
||||||
|
if(!NetPlayerClient.connect(addy,port)) {
|
||||||
|
useSMserver = -1; //If connection to socket fails, tell
|
||||||
|
//other network functions to not do anything
|
||||||
|
} else {
|
||||||
|
useSMserver = 1; //Utilize other network funtions
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkSyncManager::ReportScore (int playerID, int step, int score, int combo)
|
||||||
|
{
|
||||||
|
if (useSMserver!=1) //Make sure that we are using the network
|
||||||
|
return ;
|
||||||
|
|
||||||
|
netHolder SendNetPack; //Create packet to send to server
|
||||||
|
|
||||||
|
SendNetPack.m_playerID = playerID;
|
||||||
|
SendNetPack.m_combo=combo;
|
||||||
|
SendNetPack.m_score=score; //Load packet with aproperate info
|
||||||
|
SendNetPack.m_step=step-1;
|
||||||
|
|
||||||
|
NetPlayerClient.send((char*)&SendNetPack, sizeof(netHolder));
|
||||||
|
//Send packet to server
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkSyncManager::ReportSongOver ()
|
||||||
|
{
|
||||||
|
if (useSMserver!=1) //Make sure that we are using the network
|
||||||
|
return ;
|
||||||
|
|
||||||
|
netHolder SendNetPack; //Create packet to send to server
|
||||||
|
|
||||||
|
SendNetPack.m_playerID = 21;
|
||||||
|
SendNetPack.m_combo=0;
|
||||||
|
SendNetPack.m_score=0; //Use PID 21 (Song over Packet)
|
||||||
|
SendNetPack.m_step=0;
|
||||||
|
|
||||||
|
NetPlayerClient.send((char*)&SendNetPack, sizeof(netHolder));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkSyncManager::StartRequest ()
|
||||||
|
{
|
||||||
|
if (useSMserver!=1)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
vector <char> tmp; //Temporary vector used by receive function
|
||||||
|
//when waiting
|
||||||
|
|
||||||
|
LOG->Trace("Requesting Start from Server.");
|
||||||
|
|
||||||
|
netHolder SendNetPack;
|
||||||
|
|
||||||
|
SendNetPack.m_playerID = 20;
|
||||||
|
SendNetPack.m_combo=0;
|
||||||
|
SendNetPack.m_score=0; //PID 20 (Song Start Request Packet)
|
||||||
|
SendNetPack.m_step=0;
|
||||||
|
|
||||||
|
NetPlayerClient.send((char*)&SendNetPack, sizeof(netHolder));
|
||||||
|
|
||||||
|
LOG->Trace("Waiting for RECV");
|
||||||
|
|
||||||
|
//Block until go is recieved.
|
||||||
|
NetPlayerClient.receive(tmp);
|
||||||
|
|
||||||
|
LOG->Trace("Starting Game.");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef NetworkSyncManager_H
|
||||||
|
#define NetworkSyncManager_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Class: NetworkSyncManager (And netholder)
|
||||||
|
|
||||||
|
Desc: Uses ezsockets for primitive song syncing and score reporting.
|
||||||
|
|
||||||
|
Copyright (c) 2003-2004 by the person(s) listed below. All rights reserved.
|
||||||
|
Charles Lohr
|
||||||
|
Joshua Allen
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ezsockets.h"
|
||||||
|
|
||||||
|
static int useSMserver; //Using network or not?
|
||||||
|
static EzSockets NetPlayerClient; //Socket used for network traffic
|
||||||
|
|
||||||
|
class NetworkSyncManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NetworkSyncManager();
|
||||||
|
~NetworkSyncManager();
|
||||||
|
|
||||||
|
void ReportScore(int playerID, int step, int score, int combo);
|
||||||
|
//If "useSMserver" then send score to server
|
||||||
|
|
||||||
|
void ReportSongOver(); //Report to server that song is over
|
||||||
|
|
||||||
|
void StartRequest(); //Request a start. Block until granted.
|
||||||
|
|
||||||
|
int Connect(char * addy, int port);
|
||||||
|
//Connect to SM Server
|
||||||
|
|
||||||
|
int m_playerID; //these are currently unused, but need to stay
|
||||||
|
int m_step;
|
||||||
|
int m_score;
|
||||||
|
int m_combo;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class netHolder //Data structure used for sending data to server
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int m_playerID; //PID (also used for Commands)
|
||||||
|
int m_step; //SID (StepID, 0-6 for Miss to Marv, 7,8 for boo and ok)
|
||||||
|
int m_score; //Player's Score
|
||||||
|
int m_combo; //Player's Current Combo
|
||||||
|
};
|
||||||
|
|
||||||
|
//Static this class inside itself
|
||||||
|
//so that other parts of the program that include
|
||||||
|
//NetworkSyncManager can use "currentNetPlayer"
|
||||||
|
static NetworkSyncManager currentNetPlayer;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
/*******************************************
|
||||||
|
ezsockets.cpp -- Header for sockets.cpp
|
||||||
|
Designed by Josh Allen and Charles
|
||||||
|
Lohr. Socket programming methods based
|
||||||
|
on Charles Lohr's EZW progam.
|
||||||
|
You may freely destribute this code
|
||||||
|
if this message is retained.
|
||||||
|
This code is distributed on an as-is
|
||||||
|
basis with no gaurentees whatsoever.
|
||||||
|
|
||||||
|
Modified by Charles Lohr for use with
|
||||||
|
Windows-Based OSes.
|
||||||
|
********************************************/
|
||||||
|
|
||||||
|
#pragma comment(lib,"wsock32.lib")
|
||||||
|
//We need the Winsock32 Libary
|
||||||
|
|
||||||
|
#include "ezsockets.h"
|
||||||
|
|
||||||
|
EzSockets::EzSockets() {
|
||||||
|
MAXCON = 5;
|
||||||
|
memset (&addr, 0, sizeof(addr)); //Clear the sockaddr_in structure
|
||||||
|
|
||||||
|
//Windows REQUIRES WinSock Startup
|
||||||
|
#if defined(WIN32)
|
||||||
|
WSAStartup(MAKEWORD(1,1), &wsda);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EzSockets::~EzSockets() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::check() {
|
||||||
|
//Check to see if the socket ahs been created
|
||||||
|
if (sock < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EzSockets::create() {
|
||||||
|
sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::bind(int port) {
|
||||||
|
|
||||||
|
if (!check()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
addr.sin_port = htons (port);
|
||||||
|
|
||||||
|
int desc = ::bind(sock, (struct sockaddr *) & addr, sizeof(addr));
|
||||||
|
if (desc < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::listen() {
|
||||||
|
int desc = ::listen(sock, MAXCON);
|
||||||
|
if (desc < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::accept(EzSockets &socket) {
|
||||||
|
|
||||||
|
//Windows wants it defined as a signed int
|
||||||
|
#if defined(WIN32)
|
||||||
|
int length = sizeof(socket);
|
||||||
|
#else
|
||||||
|
unsigned int length = sizeof(socket);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
socket.sock = ::accept(sock, (struct sockaddr *) & socket.addr,& length);
|
||||||
|
if (socket.sock < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EzSockets::close() {
|
||||||
|
//The close socket command is different in Windows
|
||||||
|
#if defined(WIN32)
|
||||||
|
::closesocket(sock);
|
||||||
|
#else
|
||||||
|
::close(sock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::receiveLength(int &length) {
|
||||||
|
length = 0;
|
||||||
|
|
||||||
|
//cannot send in void* in Windows.
|
||||||
|
#if defined(WIN32)
|
||||||
|
int desc = recv(sock, (char*)&length, sizeof(int),0);
|
||||||
|
#else
|
||||||
|
int desc = recv(sock, (void*)&length, sizeof(int),0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (desc <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::receive(int &x) {
|
||||||
|
if (!receiveLength(x)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::receive(std::vector<char> &data) {
|
||||||
|
char buf[1024];
|
||||||
|
/* If the length is less than 1024 then receive
|
||||||
|
all the data in one recv() command. If the
|
||||||
|
length is greater than 1024 receive data
|
||||||
|
with multiple recv() commands.
|
||||||
|
*/
|
||||||
|
int desc=0;
|
||||||
|
int length;
|
||||||
|
length = 0;
|
||||||
|
data.resize(0);
|
||||||
|
if (!receiveLength(length)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (length <= 1024) {
|
||||||
|
memset (&buf, 0, sizeof(buf));
|
||||||
|
desc = recv(sock, buf, 1024, 0);
|
||||||
|
for (int x = 0;x < desc;x++) {
|
||||||
|
data.push_back(buf[x]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (int(data.size()) < length) {
|
||||||
|
memset (&buf, 0, sizeof(buf)); //Flush the buffer
|
||||||
|
desc = recv(sock, buf, 1024,0);
|
||||||
|
for (int x = 0;x < desc;x++) {
|
||||||
|
data.push_back(buf[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (desc <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Make sure data is the correct size.
|
||||||
|
This maybe uneeded but seems like
|
||||||
|
a good idea.
|
||||||
|
*/
|
||||||
|
data.resize(length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::send(std::string data) {
|
||||||
|
/* First send send the length of the data to the
|
||||||
|
server. Then if the length is less than or equal
|
||||||
|
to the 1024 then send data in one sendData()
|
||||||
|
commans. If data is larger then 1024 than
|
||||||
|
send the data in multiple sendData() commands.
|
||||||
|
Each sendData() sends as much data as 1024.
|
||||||
|
HAVE NOT CHECK TO SEE IF TRANSFER OF LARGE DATA
|
||||||
|
IS CORRECT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int desc = sendLength(data.length());
|
||||||
|
if (desc == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (data.length() <= (1024)) {
|
||||||
|
desc = sendData((char*)data.c_str(), data.length());
|
||||||
|
if (desc == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int x = 0;x < int(data.length());x += 1024) {
|
||||||
|
desc = sendData((char*)std::string(data.substr(x, x+1024)).c_str());
|
||||||
|
}
|
||||||
|
if (desc == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::send(char *data, int length) {
|
||||||
|
/* Sends the data in chunks of 1024. Appears to
|
||||||
|
work fine with large and small data ammounts.
|
||||||
|
*/
|
||||||
|
int desc;
|
||||||
|
char buf[1024];
|
||||||
|
desc = sendLength(length);
|
||||||
|
if (desc == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int x = 0;x < length;x += 1024) {
|
||||||
|
memset (&buf, 0, sizeof(buf));
|
||||||
|
for (int bytes = 0;bytes < 1024;bytes++) {
|
||||||
|
buf[bytes] = (char)data[x+bytes];
|
||||||
|
}
|
||||||
|
if (length < 1024) {
|
||||||
|
desc = sendData(buf, length);
|
||||||
|
} else {
|
||||||
|
desc = sendData(buf);
|
||||||
|
}
|
||||||
|
if (desc == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::sendLength(int length) {
|
||||||
|
#if defined(WIN32)
|
||||||
|
int desc = ::send(sock, (char*)&length, sizeof(int), 0);
|
||||||
|
#else
|
||||||
|
int desc = ::send(sock, (void*)&length, sizeof(int), 0);
|
||||||
|
#endif
|
||||||
|
if (desc <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::send(int x) {
|
||||||
|
if (!sendLength(x)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::sendData(char data[1024], int size) {
|
||||||
|
/*This function sends data just fine.
|
||||||
|
Problem is with the reassemble while
|
||||||
|
receiving data.*/
|
||||||
|
int desc;
|
||||||
|
int lpos = 0;
|
||||||
|
|
||||||
|
if (size==0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
while (size-lpos > 0) {
|
||||||
|
desc = ::send(sock, *((&data)+lpos), size, 0);
|
||||||
|
if (desc<=0)
|
||||||
|
return false;
|
||||||
|
lpos=lpos+desc;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EzSockets::connect(std::string host, int port) {
|
||||||
|
if (!check()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
struct hostent* phe;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
phe = gethostbyname(host.c_str());
|
||||||
|
addr.sin_addr = *((LPIN_ADDR)*phe->h_addr_list);
|
||||||
|
|
||||||
|
int desc = ::connect(sock,(struct sockaddr *)&addr,sizeof(addr));
|
||||||
|
#else
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
int status = inet_pton ( AF_INET, host.c_str(), &addr.sin_addr );
|
||||||
|
|
||||||
|
int desc = ::connect(sock,(struct sockaddr *)&addr,sizeof(addr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (desc < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
long EzSockets::uAddr() {
|
||||||
|
return addr.sin_addr.s_addr;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*******************************************
|
||||||
|
ezsockets.h -- Header for sockets.cpp
|
||||||
|
Designed by Josh Allen and Charles
|
||||||
|
Lohr. Socket programming methods based
|
||||||
|
on Charles Lohr's EZW progam.
|
||||||
|
You may freely destribute this code
|
||||||
|
if this message is retained.
|
||||||
|
This code is distributed on an as-is
|
||||||
|
basis with no gaurentees whatsoever.
|
||||||
|
|
||||||
|
Modified by Charles Lohr for use on
|
||||||
|
windows and Unix.
|
||||||
|
********************************************/
|
||||||
|
|
||||||
|
#ifndef __EZSOCKETS_H
|
||||||
|
#define __EZSOCKETS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <winsock2.h>
|
||||||
|
#else
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/in_systm.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class EzSockets {
|
||||||
|
private:
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
WSADATA wsda;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int MAXCON;
|
||||||
|
int sock;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
bool sendData(char data[1024], int size = 1024);
|
||||||
|
bool sendLength(int length);
|
||||||
|
bool receiveLength(int &length);
|
||||||
|
public:
|
||||||
|
|
||||||
|
EzSockets();
|
||||||
|
~EzSockets();
|
||||||
|
//Check to see if Socket is active
|
||||||
|
bool check();
|
||||||
|
//Crate the socket
|
||||||
|
int create();
|
||||||
|
//Bind Socket to local port
|
||||||
|
bool bind(int port);
|
||||||
|
//Listen with socket
|
||||||
|
bool listen();
|
||||||
|
//Accept incomming socket
|
||||||
|
bool accept(EzSockets &socket);
|
||||||
|
//Receive raw data
|
||||||
|
bool receive(std::vector<char> &data);
|
||||||
|
//Receive structure
|
||||||
|
bool receive(int &x);
|
||||||
|
//Send string
|
||||||
|
bool send(std::string data);
|
||||||
|
//Send Structure (or other data)
|
||||||
|
bool send(char *data, int length);
|
||||||
|
//Send Integer
|
||||||
|
bool send(int x);
|
||||||
|
//Connect to remote host
|
||||||
|
//NOTE: YOU MUST PUT IN IP, NOT NAME
|
||||||
|
bool connect(std::string host, int port);
|
||||||
|
|
||||||
|
long uAddr();
|
||||||
|
//Kill socket
|
||||||
|
void close();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user