More networking work

This commit is contained in:
simon.kagstrom 2009-11-01 08:38:13 +00:00
parent 7be94b966a
commit 3518863b67
7 changed files with 80 additions and 8 deletions

View File

@ -27,7 +27,6 @@
#include "menutexts.h"
/* TODO: */
extern char *fixme_tmp_network_client;
extern char *fixme_tmp_network_server;

View File

@ -22,6 +22,8 @@
#include "Network.h"
#include "Display.h"
#include "Prefs.h"
#include "main.h"
#include "C64.h"
#include "menu.h"
#if defined(GEKKO)
@ -77,6 +79,7 @@ Network::Network(const char *remote_host, int port)
/* Assume black screen */
memset(this->screen, 0, DISPLAY_X * DISPLAY_Y);
memset(this->screenshot, 0, sizeof(this->screenshot));
Network::networking_started = true;
/* Peer addresses, if it fails we are out of luck */
@ -261,6 +264,30 @@ bool Network::CompareSquare(Uint8 *a, Uint8 *b)
return true;
}
void Network::EncodeScreenshot(Uint8 *dst, Uint8 *master)
{
int x, y;
int cnt = 0;
int p = 0;
memset(dst, 0, (SCREENSHOT_X * SCREENSHOT_Y) / 2);
for (y = 0; y < DISPLAY_Y; y += SCREENSHOT_FACTOR)
{
for (x = 0; x < DISPLAY_X; x += SCREENSHOT_FACTOR)
{
Uint8 col_s = master[ y * DISPLAY_X + x ];
bool is_odd = (cnt & 1) == 1;
int raw_shift = (is_odd ? 0 : 4);
/* Every second is shifted */
dst[ p ] |= (col_s << raw_shift);
if (is_odd)
p++;
cnt++;
}
}
}
void Network::EncodeDisplay(Uint8 *master, Uint8 *remote)
{
if (!Network::is_master)
@ -717,6 +744,7 @@ bool Network::MarshalData(NetworkUpdate *p)
peer->is_master = htons(peer->is_master);
peer->server_id = htonl(peer->server_id);
peer->version = htonl(peer->version);
peer->avatar = htonl(peer->avatar);
}
lp->n_peers = htonl(lp->n_peers);
lp->your_port = htons(lp->your_port);
@ -811,6 +839,7 @@ bool Network::DeMarshalData(NetworkUpdate *p)
peer->is_master = ntohs(peer->is_master);
peer->server_id = ntohl(peer->server_id);
peer->version = ntohl(peer->version);
peer->avatar = ntohl(peer->avatar);
}
lp->your_port = ntohs(lp->your_port);
} break;
@ -915,6 +944,9 @@ bool Network::ConnectToBroker()
pi->is_master = Network::is_master;
pi->key = ThePrefs.NetworkKey;
pi->version = FRODO_NETWORK_PROTOCOL_VERSION;
pi->avatar = ThePrefs.NetworkAvatar;
this->EncodeScreenshot(pi->screenshot, TheC64->TheDisplay->BitmapBase());
strcpy((char*)pi->name, ThePrefs.NetworkName);
this->AddNetworkUpdate(ud);
out = this->SendUpdate();

View File

@ -18,6 +18,10 @@
#define NETWORK_UPDATE_SIZE (256 * 1024)
#define NETWORK_SOUND_BUF_SIZE 4096
#define SCREENSHOT_FACTOR 4
#define SCREENSHOT_X (DISPLAY_X / SCREENSHOT_FACTOR)
#define SCREENSHOT_Y (DISPLAY_Y / SCREENSHOT_FACTOR)
typedef enum
{
/* Connection-related messages */
@ -119,6 +123,10 @@ struct NetworkUpdatePeerInfo
uint8 name[32]; /* "SIMON", "LINDA" etc */
uint32 server_id; /* Used by the server */
uint32 version; /* Version number */
uint32 avatar; /* Hash of the avatar */
/* RAW-encoded screenshot of how the display looks like */
uint8 screenshot[(SCREENSHOT_X * SCREENSHOT_Y) / 2];
};
struct NetworkUpdateListPeers
@ -150,6 +158,8 @@ public:
void EncodeSound();
void EncodeScreenshot(Uint8 *dst, Uint8 *master);
void EncodeDisplay(Uint8 *master, Uint8 *remote);
void EncodeJoystickUpdate(Uint8 v);
@ -337,6 +347,7 @@ protected:
Uint8 *rle_buf;
Uint8 *diff_buf;
Uint8 *sound_buf;
Uint8 screenshot[SCREENSHOT_X * SCREENSHOT_Y / 2];
Uint32 *square_updated;
size_t traffic, last_traffic;

View File

@ -102,6 +102,7 @@ Prefs::Prefs()
this->MsPerFrame = 28;
#endif
this->NetworkKey = rand() % 0xffff;
this->NetworkAvatar = 0;
snprintf(this->NetworkName, 32, "Unset name");
}
@ -180,6 +181,7 @@ bool Prefs::operator==(const Prefs &rhs) const
&& this->MsPerFrame == rhs.MsPerFrame
#endif
&& this->NetworkKey == rhs.NetworkKey
&& this->NetworkAvatar == rhs.NetworkAvatar
&& strcmp(this->NetworkName, rhs.NetworkName) == 0
);
}
@ -366,6 +368,8 @@ void Prefs::Load(char *filename)
NetworkKey = atoi(value);
else if (!strcmp(keyword, "NetworkName"))
strcpy(NetworkName, value);
else if (!strcmp(keyword, "NetworkAvatar"))
NetworkAvatar = atoi(value);
#endif
}
}
@ -458,6 +462,7 @@ bool Prefs::Save(char *filename)
fprintf(file, "DisplayOption = %d\n", DisplayOption);
fprintf(file, "MsPerFrame = %d\n", MsPerFrame);
fprintf(file, "NetworkKey = %d\n", NetworkKey);
fprintf(file, "NetworkAvatar = %d\n", NetworkAvatar);
fprintf(file, "NetworkName = %s\n", NetworkName);
#endif
fclose(file);

View File

@ -155,6 +155,7 @@ private:
#endif
char NetworkName[32];
int NetworkKey;
uint32 NetworkAvatar;
};

View File

@ -103,17 +103,13 @@ Frodo::Frodo()
/*
* Process command line arguments
*/
char *fixme_tmp_network_client = 0;
char *fixme_tmp_network_server = 0;
void Frodo::ArgvReceived(int argc, char **argv)
{
if (argc == 3)
if (argc == 2)
{
if (strcmp(argv[1], "-s") == 0)
fixme_tmp_network_server = argv[2];
else if (strcmp(argv[1], "-c") == 0)
fixme_tmp_network_client = argv[2];
fixme_tmp_network_server = argv[1];
}
}

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
import socket, struct, syslog, time, thread, ip2country, sys
import SocketServer, stats
import SocketServer, stats, image
FRODO_NETWORK_PROTOCOL_VERSION = 4
FRODO_NETWORK_MAGIC = 0x1976
@ -125,6 +125,8 @@ class ConnectToBrokerPacket(Packet):
self.type = CONNECT_TO_BROKER
self.name = ""
self.server_id = 0
self.avatar = 0
self.screenshot = ""
def demarshal_from_data(self, data):
Packet.demarshal_from_data(self, data)
@ -137,9 +139,21 @@ class ConnectToBrokerPacket(Packet):
self.name = self.name[0:self.name.find('\0')]
if self.version >= 4:
self.avatar = struct.unpack(">L", data[88:92])[0]
self.screenshot = struct.unpack(">%dB" % (image.SCREENSHOT_SIZE),
data[92:92 + image.SCREENSHOT_SIZE])[0]
print "VOBB", self.screenshot
def get_key(self):
return self.key
def get_avatar(self):
return self.avatar
def get_screenshot(self):
return self.screenshot
def get_name(self):
return self.name
@ -160,6 +174,10 @@ class ListPeersPacket(Packet):
self.n_peers = self.n_peers + 1
self.size = self.size + 80
# Add avatar and screenshot size
if self.version >= 4:
self.size = self.size + image.SCREENSHOT_SIZE + 4
def marshal(self):
out = struct.pack(">L16sHxx", self.n_peers, "", 0)
@ -172,6 +190,10 @@ class ListPeersPacket(Packet):
peer.public_ip, peer.key,
peer.is_master, name,
0, peer.id, self.version)
if self.version >= 4:
print "Marshalling", peer.screenshot
out = out + struct.pack(">L%dB" % (image.SCREENSHOT_SIZE),
peer.avatar, peer.screenshot)
return Packet.marshal(self) + out
@ -206,6 +228,9 @@ class Peer:
self.is_master = 0
self.id = id
self.avatar = 0
self.screenshot = ""
# Assume it's alive now
self.last_ping = cur_time()
@ -231,6 +256,9 @@ class Peer:
self.send_packet(lp.marshal())
return
self.avatar = pkt.get_avatar()
self.screenshot = pkt.get_screenshot()
self.srv.log_connection(self.name, self.country)
# Send list of peers if this is not a master