2002-11-23 Al Riddoch <alriddoch@zepler.org>
* Increment to devel version 0.3, and start breaking things.
* server/CommClient.cpp, server/CommClient.h, server/CommServer.cpp,
server/CommServer.h, server/server.cpp, server/CommListener.cpp,
server/CommListener.h, server/CommMetaClient.cpp,
server/CommMetaClient.h, server/CommSocket.cpp, server/CommSocket.h:
Refactor network code so metaserver and listen socket are no longer
special cases, opening up the way for a database connection handler.
2002-11-23 17:13:39 +00:00
|
|
|
// This file may be redistributed and modified only under the terms of
|
|
|
|
|
// the GNU General Public License (See COPYING for details).
|
|
|
|
|
// Copyright (C) 2000,2001 Alistair Riddoch
|
|
|
|
|
|
|
|
|
|
#include "CommMetaClient.h"
|
|
|
|
|
|
|
|
|
|
#include "protocol_instructions.h"
|
|
|
|
|
|
2003-03-07 00:22:12 +00:00
|
|
|
#include "common/debug.h"
|
|
|
|
|
#include "common/log.h"
|
|
|
|
|
#include "common/globals.h"
|
2002-11-23 Al Riddoch <alriddoch@zepler.org>
* Increment to devel version 0.3, and start breaking things.
* server/CommClient.cpp, server/CommClient.h, server/CommServer.cpp,
server/CommServer.h, server/server.cpp, server/CommListener.cpp,
server/CommListener.h, server/CommMetaClient.cpp,
server/CommMetaClient.h, server/CommSocket.cpp, server/CommSocket.h:
Refactor network code so metaserver and listen socket are no longer
special cases, opening up the way for a database connection handler.
2002-11-23 17:13:39 +00:00
|
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const bool debug_flag = false;
|
|
|
|
|
|
|
|
|
|
static inline char *pack_uint32(uint32_t data, char *buffer, unsigned int *size)
|
|
|
|
|
{
|
|
|
|
|
uint32_t netorder;
|
|
|
|
|
|
|
|
|
|
netorder = htonl(data);
|
|
|
|
|
memcpy(buffer, &netorder, sizeof(uint32_t));
|
|
|
|
|
*size += sizeof(uint32_t);
|
|
|
|
|
return buffer+sizeof(uint32_t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline char *unpack_uint32(uint32_t *dest, char *buffer)
|
|
|
|
|
{
|
|
|
|
|
uint32_t netorder;
|
|
|
|
|
|
|
|
|
|
memcpy(&netorder, buffer, sizeof(uint32_t));
|
|
|
|
|
*dest = ntohl(netorder);
|
|
|
|
|
return buffer+sizeof(uint32_t);
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-28 Al Riddoch <alriddoch@zepler.org>
* common/BaseEntity.cpp, common/BaseEntity.h, rulesets/Character.cpp,
rulesets/Food.cpp, rulesets/Thing.cpp, rulesets/World.cpp:
Add arg to error method specifying where the error should go. Use
this arg to ensure that errors don't get broadcast.
* common/Database.cpp, common/Database.h, common/const.cpp,
server/Persistor.cpp, server/Restoration.cpp,
server/WorldRouter.cpp
Change id and loc column in entity tables to integer for
performance. Add id generator sequence to database
* common/Database.cpp, common/Database.h, server/Persistance.cpp,
server/Persistance.h: Remove old legacy world, mind and server
tables as they are no longer used.
* common/BaseEntity.cpp, common/Load.h, common/Save.h,
common/custom.cpp, common/op_switch.h, common/operations.cpp,
common/operations.h, common/types.h, rulesets/BaseMind.cpp,
rulesets/BaseMind.h, rulesets/Character.cpp, rulesets/Character.h,
server/Admin.cpp, server/Admin.h, server/server.cpp,
tools/cycmd.cpp: Remove Load and Save ops.
* rulesets/Area.cpp, rulesets/Character.cpp, rulesets/Line.cpp,
rulesets/Plant.cpp: Fix != to |= when setting update flags.
* server/CommMetaClient.cpp, server/CommMetaClient.h,
server/CommServer.cpp, server/CommServer.h, server/server.cpp:
Add mechanism for sockets to be called whenever the server
is idle, so that they do period things. Use this mechanis,
to handle sending periodic packets to the metaserver, removing
special case code from CommServer.
2002-12-28 21:52:32 +00:00
|
|
|
CommMetaClient::~CommMetaClient()
|
|
|
|
|
{
|
|
|
|
|
metaserverTerminate();
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-23 Al Riddoch <alriddoch@zepler.org>
* Increment to devel version 0.3, and start breaking things.
* server/CommClient.cpp, server/CommClient.h, server/CommServer.cpp,
server/CommServer.h, server/server.cpp, server/CommListener.cpp,
server/CommListener.h, server/CommMetaClient.cpp,
server/CommMetaClient.h, server/CommSocket.cpp, server/CommSocket.h:
Refactor network code so metaserver and listen socket are no longer
special cases, opening up the way for a database connection handler.
2002-11-23 17:13:39 +00:00
|
|
|
int CommMetaClient::getFd() const
|
|
|
|
|
{
|
|
|
|
|
return metaFd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CommMetaClient::eof()
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
bool CommMetaClient::isOpen() const
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CommMetaClient::read()
|
|
|
|
|
{
|
|
|
|
|
metaserverReply();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CommMetaClient::setup(const std::string & mserver)
|
|
|
|
|
{
|
|
|
|
|
// Establish socket for communication with the metaserver
|
|
|
|
|
memset(&meta_sa, 0, sizeof(meta_sa));
|
|
|
|
|
meta_sa.sin_family = AF_INET;
|
2002-11-23 17:35:50 +00:00
|
|
|
meta_sa.sin_port = htons(metaserverPort);
|
2002-11-23 Al Riddoch <alriddoch@zepler.org>
* Increment to devel version 0.3, and start breaking things.
* server/CommClient.cpp, server/CommClient.h, server/CommServer.cpp,
server/CommServer.h, server/server.cpp, server/CommListener.cpp,
server/CommListener.h, server/CommMetaClient.cpp,
server/CommMetaClient.h, server/CommSocket.cpp, server/CommSocket.h:
Refactor network code so metaserver and listen socket are no longer
special cases, opening up the way for a database connection handler.
2002-11-23 17:13:39 +00:00
|
|
|
|
|
|
|
|
debug(std::cout << "Connecting to metaserver..." << std::endl << std::flush;);
|
|
|
|
|
struct hostent * ms_addr = ::gethostbyname(mserver.c_str());
|
|
|
|
|
if (ms_addr == NULL) {
|
|
|
|
|
log(WARNING, "metaserver lookup failed. Disabling metaserver");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
memcpy(&meta_sa.sin_addr, ms_addr->h_addr_list[0], ms_addr->h_length);
|
|
|
|
|
|
|
|
|
|
metaFd = ::socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
if (metaFd < 0) {
|
|
|
|
|
log(WARNING, "Could not connect to metaserver. Disabling metaserver");
|
|
|
|
|
perror("socket");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-23 17:35:50 +00:00
|
|
|
static const int MAXLINE = 4096;
|
2002-11-23 Al Riddoch <alriddoch@zepler.org>
* Increment to devel version 0.3, and start breaking things.
* server/CommClient.cpp, server/CommClient.h, server/CommServer.cpp,
server/CommServer.h, server/server.cpp, server/CommListener.cpp,
server/CommListener.h, server/CommMetaClient.cpp,
server/CommMetaClient.h, server/CommSocket.cpp, server/CommSocket.h:
Refactor network code so metaserver and listen socket are no longer
special cases, opening up the way for a database connection handler.
2002-11-23 17:13:39 +00:00
|
|
|
|
|
|
|
|
void CommMetaClient::metaserverKeepalive()
|
|
|
|
|
{
|
|
|
|
|
char mesg[MAXLINE];
|
|
|
|
|
unsigned int packet_size = 0;
|
|
|
|
|
|
|
|
|
|
pack_uint32(SKEEP_ALIVE, mesg, &packet_size);
|
|
|
|
|
sendto(metaFd,mesg,packet_size,0, (sockaddr *)&meta_sa, sizeof(meta_sa));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CommMetaClient::metaserverReply()
|
|
|
|
|
{
|
|
|
|
|
char mesg[MAXLINE];
|
|
|
|
|
char *mesg_ptr;
|
|
|
|
|
uint32_t handshake = 0, command = 0;
|
2002-12-17 17:44:46 +00:00
|
|
|
struct sockaddr addr;
|
|
|
|
|
socklen_t addrlen = sizeof(addr);
|
2002-11-23 Al Riddoch <alriddoch@zepler.org>
* Increment to devel version 0.3, and start breaking things.
* server/CommClient.cpp, server/CommClient.h, server/CommServer.cpp,
server/CommServer.h, server/server.cpp, server/CommListener.cpp,
server/CommListener.h, server/CommMetaClient.cpp,
server/CommMetaClient.h, server/CommSocket.cpp, server/CommSocket.h:
Refactor network code so metaserver and listen socket are no longer
special cases, opening up the way for a database connection handler.
2002-11-23 17:13:39 +00:00
|
|
|
unsigned int packet_size;
|
|
|
|
|
|
|
|
|
|
if (recvfrom(metaFd, mesg, MAXLINE, 0, &addr, &addrlen) < 0) {
|
|
|
|
|
log(WARNING, "WARNING: No reply from metaserver");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
mesg_ptr = unpack_uint32(&command, mesg);
|
|
|
|
|
|
|
|
|
|
if(command == HANDSHAKE)
|
|
|
|
|
{
|
|
|
|
|
mesg_ptr = unpack_uint32(&handshake, mesg_ptr);
|
2002-11-23 17:35:50 +00:00
|
|
|
debug(std::cout << "MetaServer contacted successfully."
|
|
|
|
|
<< std::endl << std::flush;);
|
2002-11-23 Al Riddoch <alriddoch@zepler.org>
* Increment to devel version 0.3, and start breaking things.
* server/CommClient.cpp, server/CommClient.h, server/CommServer.cpp,
server/CommServer.h, server/server.cpp, server/CommListener.cpp,
server/CommListener.h, server/CommMetaClient.cpp,
server/CommMetaClient.h, server/CommSocket.cpp, server/CommSocket.h:
Refactor network code so metaserver and listen socket are no longer
special cases, opening up the way for a database connection handler.
2002-11-23 17:13:39 +00:00
|
|
|
|
|
|
|
|
packet_size = 0;
|
|
|
|
|
mesg_ptr = pack_uint32(SERVERSHAKE, mesg, &packet_size);
|
|
|
|
|
mesg_ptr = pack_uint32(handshake, mesg_ptr, &packet_size);
|
|
|
|
|
|
|
|
|
|
sendto(metaFd,mesg,packet_size,0,(sockaddr*)&meta_sa,sizeof(meta_sa));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CommMetaClient::metaserverTerminate()
|
|
|
|
|
{
|
|
|
|
|
char mesg[MAXLINE];
|
|
|
|
|
unsigned int packet_size = 0;
|
|
|
|
|
|
|
|
|
|
pack_uint32(TERMINATE, mesg, &packet_size);
|
|
|
|
|
sendto(metaFd,mesg,packet_size, 0, (sockaddr *)&meta_sa, sizeof(meta_sa));
|
|
|
|
|
}
|
2002-12-28 Al Riddoch <alriddoch@zepler.org>
* common/BaseEntity.cpp, common/BaseEntity.h, rulesets/Character.cpp,
rulesets/Food.cpp, rulesets/Thing.cpp, rulesets/World.cpp:
Add arg to error method specifying where the error should go. Use
this arg to ensure that errors don't get broadcast.
* common/Database.cpp, common/Database.h, common/const.cpp,
server/Persistor.cpp, server/Restoration.cpp,
server/WorldRouter.cpp
Change id and loc column in entity tables to integer for
performance. Add id generator sequence to database
* common/Database.cpp, common/Database.h, server/Persistance.cpp,
server/Persistance.h: Remove old legacy world, mind and server
tables as they are no longer used.
* common/BaseEntity.cpp, common/Load.h, common/Save.h,
common/custom.cpp, common/op_switch.h, common/operations.cpp,
common/operations.h, common/types.h, rulesets/BaseMind.cpp,
rulesets/BaseMind.h, rulesets/Character.cpp, rulesets/Character.h,
server/Admin.cpp, server/Admin.h, server/server.cpp,
tools/cycmd.cpp: Remove Load and Save ops.
* rulesets/Area.cpp, rulesets/Character.cpp, rulesets/Line.cpp,
rulesets/Plant.cpp: Fix != to |= when setting update flags.
* server/CommMetaClient.cpp, server/CommMetaClient.h,
server/CommServer.cpp, server/CommServer.h, server/server.cpp:
Add mechanism for sockets to be called whenever the server
is idle, so that they do period things. Use this mechanis,
to handle sending periodic packets to the metaserver, removing
special case code from CommServer.
2002-12-28 21:52:32 +00:00
|
|
|
|
|
|
|
|
void CommMetaClient::idle(time_t t)
|
|
|
|
|
{
|
|
|
|
|
if (t > (lastTime + 5 * 60)) {
|
|
|
|
|
lastTime = t;
|
|
|
|
|
metaserverKeepalive();
|
|
|
|
|
}
|
|
|
|
|
}
|