274 lines
7.1 KiB
C
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 );
|
|
}
|
|
|