Files
pvvmud/worldsrv/worldsrv.C
2025-03-05 08:37:43 +01:00

274 lines
7.1 KiB
C

/*
* PVVMUD a 3D MUD
* Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "pvvmud.H"
#include <iostream.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include "socket.H"
#include "worldsrv.H"
#include "worldclimanager.H"
#include "worldsrvmanager.H"
#include "inetaddress.H"
CWorldSrv::CWorldSrv(COption *option){
m_timeKeeper = new CTimeKeeper();
m_cliManagerList = new CObjectList();
m_srvManager = NULL;
m_worldGOS = NULL;
m_srvSocket = NULL;
m_world = new CWorldSrvWorld();
CClientSocket * socket = NULL;
try {
CInetAddress server(option->getString("server"),SERVER_WORLDSRV_PORT);
socket = new CClientSocket(server.getAddress(),server.getPort());
socket->setNonBlocking();
cout << "WorldSrv Server manager connected\n";
addSrvManager( new CWorldSrvManager(this, new CWorldSrvProtocol(socket,m_timeKeeper)));
} catch (CSocketException * e){
cout << "Failed to connect to server!\n";
delete e;
startSrvSocket();
}
try {
m_cliSocket = new CWorldCliSrvSocket(this,option->getString("address"),option->getInt("port"),m_timeKeeper);
} catch (CSocketException * e){
cout << "Failed to create client SrvSocket!\n";
delete e;
exit(1);
}
m_timeKeeper->addHeartBeat(512,this);
}
CWorldSrv::~CWorldSrv(){
m_timeKeeper->rmHeartBeat(this);
m_cliManagerList->deleteAll();
delete m_cliManagerList;
if (m_srvManager != NULL) delete m_srvManager;
m_cliSocket->close();
delete m_cliSocket;
stopSrvSocket();
delete m_timeKeeper;
if (m_worldGOS != NULL) delete m_worldGOS;
}
void CWorldSrv::setGOS(CInetAddress & gosAddress){
cout << "Connecting to GOS: gosAddress not used!\n";
if (m_worldGOS != NULL) delete m_worldGOS;
try {
m_worldGOS = new CWorldGOS(this,m_timeKeeper,&gosAddress);
} catch (CException *e) {
cout << *e << "Error : in CWorldGOS\n";
}
}
CInetAddress &CWorldSrv::getAddress(){
return m_cliSocket->getLocalAddress();
}
int CWorldSrv::timeKeeperHB(){
// cout << "Heart beat\n";
if (m_world != NULL) m_world->animate();
// If clients are marked with quit remove them
CObjectListItem * item = m_cliManagerList->getFirst();
while (item != NULL){
CWorldCliManager * cliManager = (CWorldCliManager*)item->getObject();
item = item->getNext();
if (cliManager->getQuit()){
int id = cliManager->getId();
removeCliManager(cliManager);
cout << "Client " << id << " deleted\n";
}
}
if ((m_srvSocket != NULL) && (m_srvSocket->getQuit())){
stopSrvSocket();
}
if (m_srvManager != NULL){
if ( m_srvManager->getQuit()){
removeSrvManager(m_srvManager);
cout << "WorldSrv Server manager deleted\n";
} else {
m_srvManager->sendPing();
}
}
return TRUE;
}
void CWorldSrv::addCliManager(CWorldCliManager * cliManager){
m_cliManagerList->addLast((CObject*)cliManager);
}
void CWorldSrv::removeCliManager(CWorldCliManager * cliManager){
m_cliManagerList->remove((CObject*)cliManager);
delete cliManager;
}
void CWorldSrv::addSrvManager(CWorldSrvManager * srvManager){
if (m_srvManager != NULL){
cout << "WARNING: Multiple servers connected!!\nDeleting old server\n";
delete m_srvManager;
}
m_srvManager = srvManager;
}
void CWorldSrv::removeSrvManager(CWorldSrvManager * srvManager){
if (srvManager != m_srvManager){
cout << "WARNING: Removing a not assigned server!\n";
delete srvManager;
} else {
delete m_srvManager;
m_srvManager = NULL;
startSrvSocket();
}
}
void CWorldSrv::startSrvSocket(){
if (m_srvSocket != NULL){
cout << "WARNING: Server SrvSocket started!\n";
}
try {
m_srvSocket = new CWorldSrvSrvSocket(this,WORLDSRV_SERVER_PORT,m_timeKeeper);
cout << "Server SrvSocket started\n";
} catch (CSocketException * e){
cout << "Failed to create server SrvSocket!\n";
delete e;
}
}
void CWorldSrv::stopSrvSocket(){
if (m_srvSocket != NULL){
m_srvSocket->close();
delete m_srvSocket;
m_srvSocket = NULL;
cout << "Server SrvSocket stoped\n";
}
}
void CWorldSrv::quit(){
m_timeKeeper->stopLoop();
}
void CWorldSrv::restart(){
}
void CWorldSrv::run(){
m_timeKeeper->mainLoop();
}
void CWorldSrv::createWorld(){
cout << "World created!\n";
m_world->clearWorld();
}
/*
void CWorldSrv::addCell( DWORD cellId, DWORD geometryId ){
cout << "Create cell " << cellId << "\n";
m_world->addCell(cellId,geometryId);
}
void CWorldSrv::removeCell( DWORD cellId ){
cout << "Delete cell " << cellId << "\n";
m_world->removeCell(cellId);
}
*/
void CWorldSrv::addObject( DWORD objectId, DWORD geometryId, DWORD parentId,
const CPosition & position, const CDirection & direction ){
cout << "Create object " << objectId << " with geometry " << geometryId
<< " parent: ";
(parentId != 0xFFFFFFFF ? cout << parentId : cout << -1 );
cout << " position " << position << " direction " << direction << "\n";
m_world->createObject(parentId,"object",objectId,geometryId,position,direction);
}
void CWorldSrv::removeObject( DWORD objectId, DWORD parentId ){
cout << "Delete object " << objectId << " with parent ";
(parentId != 0xFFFFFFFF ? cout << parentId : cout << -1 );
cout << "\n";
m_world->removeObject(objectId,parentId);
}
void CWorldSrv::addPVCell( DWORD cellId,
DWORD PVCellId, const CPosition & position ){
cout << "Add PVCell " << PVCellId << " to cell " << cellId
<< " with position " << position;
if (m_world->addPVCell(cellId,PVCellId,position)==NULL){
cout << " : Failed";
}
cout << "\n";
}
void CWorldSrv::updatePosition( DWORD objectId, const CPosition& position){
cout << "Update position to object " << objectId << " position "
<< position << "\n";
m_world->updatePosition( objectId, position );
}
void CWorldSrv::updateDirection( DWORD objectId, const CDirection& direction){
cout << "Update direction to object " << objectId << " direction "
<< direction << "\n";
m_world->updateDirection( objectId, direction );
}
void CWorldSrv::updateHierarchy( DWORD objectId, DWORD parentId){
cout << "Update hierarchy to object " << objectId << ". New parent "
<< parentId << "\n";
m_world->updateHierarchy( objectId, parentId );
}
void CWorldSrv::rotate( DWORD objectId, const CDirection& angleSpeed){
cout << "Rotate object " << objectId << " with angle speed "
<< angleSpeed << "\n";
m_world->rotate( objectId, angleSpeed );
}