These are the files necessiary for making the network work.

This commit is contained in:
Charles Lohr
2004-03-16 22:34:48 +00:00
parent a25514777a
commit 4af6c609f9
4 changed files with 546 additions and 0 deletions
+116
View File
@@ -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 ;
}
+59
View File
@@ -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
+289
View File
@@ -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;
}
+82
View File
@@ -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