Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
a30202d884 | |
![]() |
9fda292e01 |
|
@ -140,9 +140,15 @@ endif()
|
|||
# The flags are used throughout src/ and test/ subdirs
|
||||
|
||||
# Special flags for boost
|
||||
set(Boost_FLAGS "-DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS")
|
||||
set(Boost_FLAGS "-DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS -DBOOST_THREAD_USE_LIB")
|
||||
|
||||
set(COLOBOT_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wold-style-cast ${CXX11_FLAGS} ${Boost_FLAGS}")
|
||||
if(PLATFORM_WINDOWS)
|
||||
set(BOOST_ASIO_FLAGS "-D_WIN32_WINNT=0x0601")
|
||||
elseif()
|
||||
set(BOOST_ASIO_FLAGS "")
|
||||
endif()
|
||||
|
||||
set(COLOBOT_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wold-style-cast ${CXX11_FLAGS} ${Boost_FLAGS} ${BOOST_ASIO_FLAGS}")
|
||||
set(COLOBOT_CXX_FLAGS_RELEASE "-O2")
|
||||
set(COLOBOT_CXX_FLAGS_DEBUG "-g -O0")
|
||||
|
||||
|
@ -216,7 +222,14 @@ set(Boost_USE_MULTITHREADED ON)
|
|||
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
|
||||
set(Boost_ADDITIONALVERSION "1.51" "1.51.0")
|
||||
find_package(Boost COMPONENTS system filesystem regex REQUIRED)
|
||||
if(PLATFORM_WINDOWS)
|
||||
set(BOOST_THREAD_COMPONENT "thread_win32")
|
||||
set(BOOST_ASIO_ADDITIONAL_LIBS ws2_32 wsock32)
|
||||
else()
|
||||
set(BOOST_THREAD_COMPONENT "thread")
|
||||
set(BOOST_ASIO_ADDITIONAL_LIBS "")
|
||||
endif()
|
||||
find_package(Boost COMPONENTS system filesystem regex ${BOOST_THREAD_COMPONENT} serialization REQUIRED)
|
||||
|
||||
find_package(GLEW REQUIRED)
|
||||
|
||||
|
|
|
@ -97,6 +97,12 @@ set(BASE_SOURCES
|
|||
graphics/engine/text.cpp
|
||||
graphics/engine/water.cpp
|
||||
graphics/opengl/gldevice.cpp
|
||||
net/connections/conn.cpp
|
||||
net/connections/connclient.cpp
|
||||
net/connections/connserver.cpp
|
||||
net/services/client.cpp
|
||||
net/services/netservice.cpp
|
||||
net/services/server.cpp
|
||||
object/auto/auto.cpp
|
||||
object/auto/autobase.cpp
|
||||
object/auto/autoconvert.cpp
|
||||
|
@ -203,6 +209,10 @@ set(MAIN_SOURCES
|
|||
${RES_FILES}
|
||||
)
|
||||
|
||||
set(DEDICATED_SERVER_SOURCES
|
||||
app/main_server.cpp
|
||||
)
|
||||
|
||||
|
||||
# Libraries
|
||||
set(LIBS
|
||||
|
@ -216,6 +226,7 @@ set(LIBS
|
|||
${PNG_LIBRARIES}
|
||||
${GLEW_LIBRARY}
|
||||
${Boost_LIBRARIES}
|
||||
${BOOST_ASIO_ADDITIONAL_LIBS}
|
||||
${LIBSNDFILE_LIBRARY}
|
||||
${OPTIONAL_LIBS}
|
||||
${PLATFORM_LIBS}
|
||||
|
@ -263,6 +274,7 @@ link_directories(
|
|||
|
||||
add_library(colobotbase STATIC ${BASE_SOURCES})
|
||||
|
||||
|
||||
add_executable(colobot ${MAIN_SOURCES})
|
||||
target_link_libraries(colobot colobotbase ${LIBS})
|
||||
|
||||
|
@ -270,3 +282,7 @@ install(TARGETS colobot RUNTIME DESTINATION ${COLOBOT_INSTALL_BIN_DIR})
|
|||
if(NOT CBOT_STATIC)
|
||||
set_target_properties(colobot PROPERTIES INSTALL_RPATH ${COLOBOT_INSTALL_LIB_DIR})
|
||||
endif()
|
||||
|
||||
|
||||
add_executable(colobot_server ${DEDICATED_SERVER_SOURCES})
|
||||
target_link_libraries(colobot_server colobotbase ${LIBS})
|
|
@ -100,7 +100,7 @@ struct ApplicationPrivate
|
|||
|
||||
|
||||
|
||||
CApplication::CApplication()
|
||||
CApplication::CApplication(bool dedicatedServer)
|
||||
{
|
||||
m_private = new ApplicationPrivate();
|
||||
m_iMan = new CInstanceManager();
|
||||
|
@ -115,6 +115,8 @@ CApplication::CApplication()
|
|||
m_controller = nullptr;
|
||||
m_sound = nullptr;
|
||||
|
||||
m_dedicatedServer = dedicatedServer;
|
||||
|
||||
m_exitCode = 0;
|
||||
m_active = false;
|
||||
m_debugModes = 0;
|
||||
|
@ -167,6 +169,8 @@ CApplication::CApplication()
|
|||
|
||||
m_runSceneName = "";
|
||||
m_runSceneRank = 0;
|
||||
|
||||
m_serverAddress = "";
|
||||
|
||||
m_sceneTest = false;
|
||||
m_headless = false;
|
||||
|
@ -234,7 +238,8 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[])
|
|||
OPT_MOD,
|
||||
OPT_VBO,
|
||||
OPT_RESOLUTION,
|
||||
OPT_HEADLESS
|
||||
OPT_HEADLESS,
|
||||
OPT_CONNECT
|
||||
};
|
||||
|
||||
option options[] =
|
||||
|
@ -252,6 +257,7 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[])
|
|||
{ "vbo", required_argument, nullptr, OPT_VBO },
|
||||
{ "resolution", required_argument, nullptr, OPT_RESOLUTION },
|
||||
{ "headless", no_argument, nullptr, OPT_HEADLESS },
|
||||
{ "connect", required_argument, nullptr, OPT_CONNECT },
|
||||
{ nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
|
@ -295,6 +301,7 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[])
|
|||
GetLogger()->Message(" -vbo mode set OpenGL VBO mode (one of: auto, enable, disable)\n");
|
||||
GetLogger()->Message(" -resolution WxH set resolution\n");
|
||||
GetLogger()->Message(" -headless headless mode - disables graphics, sound and user interaction\n");
|
||||
GetLogger()->Message(" -connect ip connect to multiplayer server\n");
|
||||
return PARSE_ARGS_HELP;
|
||||
}
|
||||
case OPT_DEBUG:
|
||||
|
@ -415,6 +422,11 @@ ParseArgsStatus CApplication::ParseArguments(int argc, char *argv[])
|
|||
m_headless = true;
|
||||
break;
|
||||
}
|
||||
case OPT_CONNECT:
|
||||
{
|
||||
m_serverAddress = optarg;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false); // should never get here
|
||||
}
|
||||
|
@ -429,6 +441,13 @@ bool CApplication::Create()
|
|||
bool defaultValues = false;
|
||||
|
||||
GetLogger()->Info("Creating CApplication\n");
|
||||
|
||||
if(m_dedicatedServer && m_runSceneName.empty()) {
|
||||
GetLogger()->Error("Mission file for dedicated server not specified\n");
|
||||
GetLogger()->Info("Please use -runscene scenename, e.g. -runscene freemissions901\n");
|
||||
m_exitCode = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::filesystem::path dataPath(m_dataPath);
|
||||
if (! (boost::filesystem::exists(dataPath) && boost::filesystem::is_directory(dataPath)) )
|
||||
|
@ -473,7 +492,7 @@ bool CApplication::Create()
|
|||
|
||||
//Create the sound instance.
|
||||
#ifdef OPENAL_SOUND
|
||||
if(!m_headless) {
|
||||
if(!m_headless && !m_dedicatedServer) {
|
||||
m_sound = static_cast<CSoundInterface *>(new ALSound());
|
||||
} else {
|
||||
m_sound = new CSoundInterface();
|
||||
|
@ -522,7 +541,7 @@ bool CApplication::Create()
|
|||
return false;
|
||||
}
|
||||
|
||||
if(!m_headless) {
|
||||
if(!m_headless && !m_dedicatedServer) {
|
||||
// load settings from profile
|
||||
int iValue;
|
||||
if ( GetProfile().GetIntProperty("Setup", "Resolution", iValue) && !m_resolutionOverride )
|
||||
|
@ -560,7 +579,7 @@ bool CApplication::Create()
|
|||
// Don't generate joystick events
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
|
||||
if(!m_headless) {
|
||||
if(!m_headless && !m_dedicatedServer) {
|
||||
// The video is ready, we can create and initalize the graphics device
|
||||
m_device = new Gfx::CGLDevice(m_deviceConfig);
|
||||
} else {
|
||||
|
@ -591,12 +610,29 @@ bool CApplication::Create()
|
|||
// Create the robot application.
|
||||
m_controller = new CController(this, !defaultValues);
|
||||
|
||||
if (m_runSceneName.empty())
|
||||
m_controller->StartApp();
|
||||
else {
|
||||
if(m_runSceneName == "custom")
|
||||
{
|
||||
m_controller->GetRobotMain()->ChangePhase(PHASE_USER); // To load userlevel list - TODO: this is ugly
|
||||
}
|
||||
|
||||
if(m_dedicatedServer)
|
||||
{
|
||||
m_controller->GetRobotMain()->SetExitAfterMission(true);
|
||||
m_controller->StartGame(m_runSceneName, m_runSceneRank/100, m_runSceneRank%100);
|
||||
m_controller->StartMPServer(m_runSceneName, m_runSceneRank/100, m_runSceneRank%100);
|
||||
} else {
|
||||
if(!m_serverAddress.empty())
|
||||
{
|
||||
m_controller->GetRobotMain()->SetExitAfterMission(true);
|
||||
m_controller->StartMPClient(m_serverAddress);
|
||||
} else {
|
||||
if(m_runSceneName.empty())
|
||||
{
|
||||
m_controller->StartApp();
|
||||
} else {
|
||||
m_controller->GetRobotMain()->SetExitAfterMission(true);
|
||||
m_controller->StartSP(m_runSceneName, m_runSceneRank/100, m_runSceneRank%100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -186,7 +186,7 @@ class CApplication : public CSingleton<CApplication>
|
|||
{
|
||||
public:
|
||||
//! Constructor (can only be called once!)
|
||||
CApplication();
|
||||
CApplication(bool dedicatedServer = false);
|
||||
//! Destructor
|
||||
~CApplication();
|
||||
|
||||
|
@ -379,6 +379,9 @@ protected:
|
|||
CProfile* m_profile;
|
||||
//! Input manager
|
||||
CInput* m_input;
|
||||
|
||||
//! Is it a dedicated server?
|
||||
bool m_dedicatedServer;
|
||||
|
||||
//! Code to return at exit
|
||||
int m_exitCode;
|
||||
|
@ -451,6 +454,9 @@ protected:
|
|||
int m_runSceneRank;
|
||||
//@}
|
||||
|
||||
//! Server to connect to
|
||||
std::string m_serverAddress;
|
||||
|
||||
//! Scene test mode
|
||||
bool m_sceneTest;
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include "app/controller.h"
|
||||
|
||||
|
||||
#include "net/services/client.h"
|
||||
#include "net/services/server.h"
|
||||
|
||||
#include "object/robotmain.h"
|
||||
|
||||
#include "ui/maindialog.h"
|
||||
|
@ -32,7 +35,7 @@ CController::CController(CApplication* app, bool loadProfile)
|
|||
{
|
||||
m_app = app;
|
||||
m_main = new CRobotMain(this);
|
||||
m_dialog = new Ui::CMainDialog();
|
||||
m_dialog = new Ui::CMainDialog(this);
|
||||
|
||||
m_main->Create(loadProfile);
|
||||
m_dialog->Create();
|
||||
|
@ -40,10 +43,16 @@ CController::CController(CApplication* app, bool loadProfile)
|
|||
m_main->CreateIni();
|
||||
else
|
||||
m_main->LoadIni();
|
||||
|
||||
m_server = nullptr;
|
||||
m_client = nullptr;
|
||||
m_multiplayer = false;
|
||||
}
|
||||
|
||||
CController::~CController()
|
||||
{
|
||||
StopGame();
|
||||
|
||||
delete m_dialog;
|
||||
m_dialog = nullptr;
|
||||
|
||||
|
@ -68,20 +77,94 @@ Ui::CMainDialog* CController::GetMainDialog()
|
|||
return m_dialog;
|
||||
}
|
||||
|
||||
CClient* CController::GetClient()
|
||||
{
|
||||
return m_client;
|
||||
}
|
||||
|
||||
CServer* CController::GetServer()
|
||||
{
|
||||
return m_server;
|
||||
}
|
||||
|
||||
void CController::StartApp()
|
||||
{
|
||||
m_main->ChangePhase(PHASE_WELCOME1);
|
||||
}
|
||||
|
||||
void CController::StartGame(std::string cat, int chap, int lvl)
|
||||
void CController::StartSP(std::string cat, int chap, int lvl)
|
||||
{
|
||||
m_dialog->SetSceneName(cat.c_str());
|
||||
m_dialog->SetSceneRank(chap*100+lvl);
|
||||
m_main->ChangePhase(PHASE_LOADING);
|
||||
m_multiplayer = false;
|
||||
}
|
||||
|
||||
void CController::StartMPServer(std::string cat, int chap, int lvl)
|
||||
{
|
||||
m_dialog->SetSceneName(cat.c_str());
|
||||
m_dialog->SetSceneRank(chap*100+lvl);
|
||||
m_main->ChangePhase(PHASE_LOADING);
|
||||
m_server = new CServer();
|
||||
m_client = nullptr;
|
||||
m_multiplayer = true;
|
||||
}
|
||||
|
||||
void CController::StartMPClient(std::string server)
|
||||
{
|
||||
m_server = nullptr;
|
||||
m_client = new CClient(server);
|
||||
m_multiplayer = true;
|
||||
}
|
||||
|
||||
void CController::StopGame()
|
||||
{
|
||||
if(m_client != nullptr)
|
||||
{
|
||||
m_client->Stop();
|
||||
delete m_client;
|
||||
m_client = nullptr;
|
||||
}
|
||||
|
||||
if(m_server != nullptr)
|
||||
{
|
||||
m_server->Stop();
|
||||
delete m_server;
|
||||
m_server = nullptr;
|
||||
}
|
||||
m_multiplayer = false;
|
||||
}
|
||||
|
||||
bool CController::IsMultiplayer()
|
||||
{
|
||||
return m_multiplayer;
|
||||
}
|
||||
|
||||
bool CController::IsServer()
|
||||
{
|
||||
return m_server != nullptr || !m_multiplayer;
|
||||
}
|
||||
|
||||
bool CController::IsClient()
|
||||
{
|
||||
return m_client != nullptr || !m_multiplayer;
|
||||
}
|
||||
|
||||
void CController::ProcessEvent(Event& event)
|
||||
{
|
||||
if(event.type == EVENT_FRAME)
|
||||
{
|
||||
if(m_client != nullptr)
|
||||
{
|
||||
m_client->ProcessEvent(event);
|
||||
}
|
||||
|
||||
if(m_server != nullptr)
|
||||
{
|
||||
m_server->ProcessEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
bool passOn = m_dialog->EventProcess(event);
|
||||
if(passOn)
|
||||
m_main->ProcessEvent(event);
|
||||
|
|
|
@ -32,6 +32,8 @@ class CRobotMain;
|
|||
namespace Ui {
|
||||
class CMainDialog;
|
||||
}
|
||||
class CServer;
|
||||
class CClient;
|
||||
|
||||
/**
|
||||
* \class CController
|
||||
|
@ -50,16 +52,39 @@ public:
|
|||
//! Return CMainDialog instance
|
||||
Ui::CMainDialog* GetMainDialog();
|
||||
|
||||
//! Return CClient instance
|
||||
CClient* GetClient();
|
||||
//! Return CServer instance
|
||||
CServer* GetServer();
|
||||
|
||||
//! Event processing
|
||||
void ProcessEvent(Event &event);
|
||||
|
||||
//! Start the application
|
||||
void StartApp();
|
||||
|
||||
//! Starts the simulation, loading the given scene
|
||||
void StartGame(std::string cat, int chap, int lvl);
|
||||
void StartSP(std::string cat, int chap, int lvl);
|
||||
//! Starts multiplayer server
|
||||
void StartMPServer(std::string cat, int chap, int lvl);
|
||||
//! Starts multiplayer client
|
||||
void StartMPClient(std::string server);
|
||||
//! Stops the simulation
|
||||
void StopGame();
|
||||
|
||||
//! Is it a multiplayer game?
|
||||
bool IsMultiplayer();
|
||||
//! Is it a server?
|
||||
bool IsServer();
|
||||
//! Is it a client?
|
||||
bool IsClient();
|
||||
|
||||
private:
|
||||
CApplication* m_app;
|
||||
CRobotMain* m_main;
|
||||
Ui::CMainDialog* m_dialog;
|
||||
|
||||
CServer* m_server;
|
||||
CClient* m_client;
|
||||
bool m_multiplayer;
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file app/main_server.cpp
|
||||
* \brief Entry point of dedicated server
|
||||
*/
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/system.h"
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/logger.h"
|
||||
#include "common/misc.h"
|
||||
#include "common/restext.h"
|
||||
|
||||
|
||||
/* Doxygen main page */
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
//! Entry point to the program
|
||||
extern "C"
|
||||
{
|
||||
|
||||
int SDL_MAIN_FUNC(int argc, char *argv[])
|
||||
{
|
||||
CLogger logger; // single istance of logger
|
||||
CResourceManager manager(argv[0]);
|
||||
|
||||
// Initialize static string arrays
|
||||
InitializeRestext();
|
||||
InitializeEventTypeTexts();
|
||||
|
||||
logger.Info("%s dedicated server starting\n", COLOBOT_FULLNAME);
|
||||
|
||||
int code = 0;
|
||||
while(true) {
|
||||
CSystemUtils* systemUtils = CSystemUtils::Create(); // platform-specific utils
|
||||
systemUtils->Init();
|
||||
|
||||
CApplication* app = new CApplication(true); // single instance of the application
|
||||
|
||||
ParseArgsStatus status = app->ParseArguments(argc, argv);
|
||||
if (status == PARSE_ARGS_FAIL)
|
||||
{
|
||||
logger.Error("Invalid commandline arguments!\n");
|
||||
return app->GetExitCode();
|
||||
}
|
||||
else if (status == PARSE_ARGS_HELP)
|
||||
{
|
||||
return app->GetExitCode();
|
||||
}
|
||||
|
||||
|
||||
if (! app->Create())
|
||||
{
|
||||
app->Destroy(); // ensure a clean exit
|
||||
code = app->GetExitCode();
|
||||
if ( code != 0 && !app->GetErrorMessage().empty() )
|
||||
{
|
||||
logger.Error("%s\n", app->GetErrorMessage().c_str());
|
||||
}
|
||||
logger.Info("Didn't run main loop. Exiting with code %d\n", code);
|
||||
return code;
|
||||
}
|
||||
|
||||
code = app->Run();
|
||||
bool restarting = app->IsRestarting();
|
||||
|
||||
delete app;
|
||||
delete systemUtils;
|
||||
if(!restarting) break;
|
||||
}
|
||||
|
||||
logger.Info("Exiting with code %d\n", code);
|
||||
return code;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/config.h"
|
||||
|
||||
#if WIN32
|
||||
#include <windows.h> // Just to make sure windows.h won't be included AFTER we remove it's macros
|
||||
// If windows.h is included somewhere, it defines these macros to point to CreateDirectoryA and RemoveDirectoryA. This makes some of our class members inaccessible
|
||||
#undef CreateDirectory
|
||||
#undef RemoveDirectory
|
||||
// This conflicts with one of Gfx::CText members
|
||||
#undef GetCharWidth
|
||||
#endif
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "graphics/core/color.h"
|
||||
|
||||
#include "math/point.h"
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "net/connections/conn.h"
|
||||
|
||||
#include "common/event.h"
|
||||
#include "common/logger.h"
|
||||
|
||||
#include "net/packets/packettype.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
CConnection::CConnection(boost::asio::io_service& service) : m_socket(service)
|
||||
{
|
||||
}
|
||||
|
||||
tcp::socket& CConnection::GetSocket()
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
void CConnection::Init()
|
||||
{
|
||||
StartReceiveHeader();
|
||||
Start();
|
||||
}
|
||||
|
||||
void CConnection::Send(PacketType packet, std::string data)
|
||||
{
|
||||
char* buf = new char[sizeof(PacketHeader)+data.length()];
|
||||
PacketHeader* p = reinterpret_cast<PacketHeader*>(buf);
|
||||
p->magic = PACKET_MAGIC;
|
||||
p->type = packet;
|
||||
p->len = data.length();
|
||||
memcpy(buf+sizeof(PacketHeader), data.c_str(), data.length());
|
||||
|
||||
boost::asio::async_write(m_socket, boost::asio::buffer(buf, sizeof(PacketHeader)+data.length()), boost::bind(&CConnection::HandleWriteFinished, this, buf));
|
||||
}
|
||||
|
||||
|
||||
void CConnection::HandleWriteFinished(char* buffer)
|
||||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void CConnection::StartReceiveHeader()
|
||||
{
|
||||
char* buf = new char[sizeof(PacketHeader)];
|
||||
boost::asio::async_read(m_socket, boost::asio::buffer(buf, sizeof(PacketHeader)), boost::bind(&CConnection::HandleReceiveHeader, this, buf, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void CConnection::HandleReceiveHeader(char* buffer, const boost::system::error_code& err)
|
||||
{
|
||||
if(!err)
|
||||
{
|
||||
PacketHeader* p = reinterpret_cast<PacketHeader*>(buffer);
|
||||
if(p->magic != PACKET_MAGIC)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Error("Received bad packet (invalid magic), disconnecting...\n");
|
||||
// TODO: Drop the connection
|
||||
// For now just keep going:
|
||||
StartReceiveHeader();
|
||||
} else {
|
||||
memcpy(&m_packetHeader, p, sizeof(PacketHeader));
|
||||
if(m_packetHeader.len > 0)
|
||||
{
|
||||
StartReceiveContent(m_packetHeader.len);
|
||||
} else {
|
||||
// This makes sure Receive() is called on the main thread
|
||||
m_recvQueue.push(ReceivedPacket(m_packetHeader.type));
|
||||
StartReceiveHeader();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CLogger::GetInstancePointer()->Error("Socket read error: %s\n", err.message().c_str());
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void CConnection::StartReceiveContent(unsigned int len)
|
||||
{
|
||||
char* buf = new char[len];
|
||||
m_socket.async_receive(boost::asio::buffer(buf, len), boost::bind(&CConnection::HandleReceiveContent, this, buf, len, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void CConnection::HandleReceiveContent(char* buffer, unsigned int len, const boost::system::error_code& err)
|
||||
{
|
||||
if(!err)
|
||||
{
|
||||
// This makes sure Receive() is called on the main thread
|
||||
m_recvQueue.push(ReceivedPacket(m_packetHeader.type, std::string(buffer, len)));
|
||||
StartReceiveHeader();
|
||||
} else {
|
||||
CLogger::GetInstancePointer()->Error("Socket read error: %s\n", err.message().c_str());
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void CConnection::EventUpdate()
|
||||
{
|
||||
while(!m_recvQueue.empty())
|
||||
{
|
||||
ReceivedPacket p = m_recvQueue.front();
|
||||
Receive(p.packet, p.data);
|
||||
m_recvQueue.pop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "src/net/packets/packettype.h"
|
||||
|
||||
#include <queue>
|
||||
#include <boost/asio.hpp>
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
class CPacketData;
|
||||
|
||||
struct ReceivedPacket
|
||||
{
|
||||
PacketType packet;
|
||||
std::string data;
|
||||
|
||||
ReceivedPacket(PacketType p, std::string d = "") : packet(p), data(d) {};
|
||||
};
|
||||
|
||||
class CConnection
|
||||
{
|
||||
public:
|
||||
CConnection(boost::asio::io_service& service);
|
||||
tcp::socket& GetSocket();
|
||||
|
||||
void Init();
|
||||
|
||||
virtual void Start() = 0;
|
||||
virtual void Receive(PacketType packet, std::string data = "") = 0;
|
||||
void Send(PacketType packet, std::string data = "");
|
||||
|
||||
void EventUpdate();
|
||||
|
||||
private:
|
||||
void HandleWriteFinished(char* buffer);
|
||||
|
||||
void StartReceiveHeader();
|
||||
void HandleReceiveHeader(char* buffer, const boost::system::error_code& err);
|
||||
void StartReceiveContent(unsigned int len);
|
||||
void HandleReceiveContent(char* buffer, unsigned int len, const boost::system::error_code& err);
|
||||
|
||||
tcp::socket m_socket;
|
||||
PacketHeader m_packetHeader;
|
||||
std::queue<ReceivedPacket> m_recvQueue;
|
||||
};
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "net/connections/connclient.h"
|
||||
|
||||
#include "app/controller.h"
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/logger.h"
|
||||
|
||||
#include "net/packets/packettype.h"
|
||||
#include "net/services/client.h"
|
||||
|
||||
#include "object/objman.h"
|
||||
#include "object/robotmain.h"
|
||||
|
||||
#include "ui/maindialog.h"
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
|
||||
CClientConnection::CClientConnection(boost::asio::io_service& service, CClient* client) : CConnection(service), m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
void CClientConnection::Start()
|
||||
{
|
||||
}
|
||||
|
||||
void CClientConnection::Receive(PacketType packet, std::string data)
|
||||
{
|
||||
switch(packet) {
|
||||
case PACKET_S_HANDSHAKE:
|
||||
PacketHandshake(data);
|
||||
break;
|
||||
|
||||
case PACKET_S_LEVEL_DATA:
|
||||
PacketLevelData(data);
|
||||
break;
|
||||
|
||||
case PACKET_S_OBJECT_UPDATE:
|
||||
PacketObjectUpdate(data);
|
||||
break;
|
||||
|
||||
case PACKET_S_DISCONNECT:
|
||||
PacketDisconnect(data);
|
||||
break;
|
||||
|
||||
default:
|
||||
CLogger::GetInstancePointer()->Error("Received bad packet (unknown type %d), disconnecting...\n", packet);
|
||||
// TODO: Drop the connection
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CClientConnection::PacketHandshake(std::string data)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Debug("Received server info packet\n");
|
||||
|
||||
std::istringstream si(data);
|
||||
boost::archive::text_iarchive ar(si);
|
||||
|
||||
std::string serverName; ar & serverName;
|
||||
std::string serverVersion; ar & serverVersion;
|
||||
if(serverVersion != COLOBOT_FULLNAME)
|
||||
CLogger::GetInstancePointer()->Warn("Version mismatch! %s != %s\n", COLOBOT_FULLNAME, serverVersion.c_str());
|
||||
ar & m_mapName;
|
||||
ar & m_mapRank;
|
||||
CLogger::GetInstancePointer()->Info("Connecting to server '%s', running map '%s%d'\n", serverName.c_str(), m_mapName.c_str(), m_mapRank);
|
||||
|
||||
|
||||
std::ostringstream so;
|
||||
boost::archive::text_oarchive ar_out(so);
|
||||
|
||||
std::string playerName = CRobotMain::GetInstancePointer()->GetGamerName(); ar_out & playerName;
|
||||
|
||||
Send(PACKET_C_CONNECT, so.str());
|
||||
}
|
||||
|
||||
void CClientConnection::PacketLevelData(std::string data)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Debug("Received level data packet\n");
|
||||
|
||||
std::istringstream si(data);
|
||||
boost::archive::text_iarchive ar(si);
|
||||
|
||||
ar & m_levelData;
|
||||
|
||||
// Load the map now
|
||||
if(m_mapName == "custom")
|
||||
{
|
||||
CController::GetInstancePointer()->GetRobotMain()->ChangePhase(PHASE_USER); // To load userlevel list - TODO: this is ugly
|
||||
}
|
||||
CController::GetInstancePointer()->GetMainDialog()->SetSceneName(m_mapName.c_str());
|
||||
CController::GetInstancePointer()->GetMainDialog()->SetSceneRank(m_mapRank);
|
||||
CController::GetInstancePointer()->GetRobotMain()->ChangePhase(PHASE_LOADING);
|
||||
}
|
||||
|
||||
const std::vector<ObjectParams>& CClientConnection::GetLevelData()
|
||||
{
|
||||
return m_levelData;
|
||||
}
|
||||
|
||||
void CClientConnection::PacketObjectUpdate(std::string data)
|
||||
{
|
||||
//CLogger::GetInstancePointer()->Debug("Received object update packet\n");
|
||||
|
||||
std::istringstream si(data);
|
||||
boost::archive::text_iarchive ar(si);
|
||||
|
||||
std::vector<ObjectParams> objects;
|
||||
ar & objects;
|
||||
|
||||
for(ObjectParams op : objects)
|
||||
{
|
||||
CObject* obj = CObjectManager::GetInstancePointer()->GetObjectById(op.id);
|
||||
if(obj == nullptr)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Error("Update about unknown object %d!\n", op.id);
|
||||
continue;
|
||||
}
|
||||
CObject* sel = CRobotMain::GetInstancePointer()->GetSelect();
|
||||
if(sel != nullptr && (obj == sel || obj == sel->GetPower() || obj == sel->GetFret())) continue;
|
||||
if(obj == m_client->m_lastLoad || obj == m_client->m_lastPower) continue;
|
||||
op.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
void CClientConnection::PacketDisconnect(std::string data)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Info("The server kicked us out :(\n");
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/connections/conn.h"
|
||||
|
||||
#include "net/packets/objectparams.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
class CClient;
|
||||
|
||||
class CClientConnection : public CConnection
|
||||
{
|
||||
public:
|
||||
CClientConnection(boost::asio::io_service& service, CClient* client);
|
||||
|
||||
void Start();
|
||||
void Receive(PacketType packet, std::string data = "");
|
||||
|
||||
//! Returns initial object positions
|
||||
const std::vector<ObjectParams>& GetLevelData();
|
||||
|
||||
private:
|
||||
void PacketHandshake(std::string data);
|
||||
void PacketLevelData(std::string data);
|
||||
void PacketObjectUpdate(std::string data);
|
||||
void PacketDisconnect(std::string data);
|
||||
|
||||
CClient* m_client;
|
||||
|
||||
std::string m_mapName;
|
||||
int m_mapRank;
|
||||
std::vector<ObjectParams> m_levelData;
|
||||
};
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "net/connections/connserver.h"
|
||||
|
||||
#include "app/controller.h"
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/logger.h"
|
||||
|
||||
#include "net/packets/objectparams.h"
|
||||
#include "net/packets/packettype.h"
|
||||
#include "net/services/server.h"
|
||||
|
||||
#include "object/object.h"
|
||||
#include "object/objman.h"
|
||||
|
||||
#include "ui/maindialog.h"
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
|
||||
CServerConnection::CServerConnection(boost::asio::io_service& service, CServer* server) : CConnection(service), m_server(server)
|
||||
{
|
||||
}
|
||||
|
||||
void CServerConnection::Start()
|
||||
{
|
||||
CLogger::GetInstancePointer()->Debug("New connection...\n");
|
||||
|
||||
std::ostringstream s;
|
||||
boost::archive::text_oarchive ar(s);
|
||||
std::string serverName = "Test server"; ar & serverName;
|
||||
std::string serverVersion = COLOBOT_FULLNAME; ar & serverVersion;
|
||||
std::string mapName = CController::GetInstancePointer()->GetMainDialog()->GetSceneName(); ar & mapName;
|
||||
int mapRank = CController::GetInstancePointer()->GetMainDialog()->GetSceneRank(); ar & mapRank;
|
||||
Send(PACKET_S_HANDSHAKE, s.str());
|
||||
}
|
||||
|
||||
void CServerConnection::Receive(PacketType packet, std::string data)
|
||||
{
|
||||
switch(packet) {
|
||||
case PACKET_C_CONNECT:
|
||||
PacketConnect(data);
|
||||
break;
|
||||
|
||||
case PACKET_C_OBJECT_UPDATE:
|
||||
PacketObjectUpdate(data);
|
||||
break;
|
||||
|
||||
case PACKET_C_DISCONNECT:
|
||||
PacketDisconnect(data);
|
||||
break;
|
||||
|
||||
default:
|
||||
CLogger::GetInstancePointer()->Error("Received bad packet (unknown type %d), disconnecting...\n", packet);
|
||||
// TODO: Drop the connection
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CServerConnection::PacketConnect(std::string data)
|
||||
{
|
||||
std::istringstream si(data);
|
||||
boost::archive::text_iarchive ar(si);
|
||||
|
||||
ar & m_playerName;
|
||||
|
||||
CLogger::GetInstancePointer()->Info("Player '%s' is connecting...\n", m_playerName.c_str());
|
||||
|
||||
|
||||
std::ostringstream so;
|
||||
boost::archive::text_oarchive ar_out(so);
|
||||
|
||||
std::vector<ObjectParams> objects;
|
||||
for(auto it : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
{
|
||||
CObject* o = it.second;
|
||||
ObjectParams op = ObjectParams::FromObject(o);
|
||||
objects.push_back(op);
|
||||
}
|
||||
ar_out & objects;
|
||||
Send(PACKET_S_LEVEL_DATA, so.str());
|
||||
}
|
||||
|
||||
void CServerConnection::PacketObjectUpdate(std::string data)
|
||||
{
|
||||
std::istringstream si(data);
|
||||
boost::archive::text_iarchive ar(si);
|
||||
std::vector<ObjectParams> objects;
|
||||
ar & objects;
|
||||
for(ObjectParams op : objects)
|
||||
{
|
||||
op.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
void CServerConnection::PacketDisconnect(std::string data)
|
||||
{
|
||||
CLogger::GetInstancePointer()->Info("'%s' disconnected\n", m_playerName.c_str());
|
||||
m_server->Broadcast(PACKET_S_DISCONNECT_NOTIFY);
|
||||
//TODO: remove from CServer's list
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/connections/conn.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
class CServer;
|
||||
|
||||
class CServerConnection : public CConnection
|
||||
{
|
||||
public:
|
||||
CServerConnection(boost::asio::io_service& service, CServer* server);
|
||||
|
||||
void Start();
|
||||
void Receive(PacketType packet, std::string data = "");
|
||||
|
||||
private:
|
||||
void PacketConnect(std::string data);
|
||||
void PacketObjectUpdate(std::string data);
|
||||
void PacketDisconnect(std::string data);
|
||||
|
||||
CServer* m_server;
|
||||
std::string m_playerName;
|
||||
};
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/packets/serialize.h"
|
||||
|
||||
#include "object/object.h"
|
||||
#include "object/objman.h"
|
||||
|
||||
#include "physics/physics.h"
|
||||
|
||||
#include <boost/serialization/array.hpp>
|
||||
|
||||
struct ObjectParams {
|
||||
int id;
|
||||
ObjectType type;
|
||||
Math::Vector pos[OBJECTMAXPART];
|
||||
Math::Vector angle[OBJECTMAXPART];
|
||||
Math::Vector speed;
|
||||
float energy;
|
||||
float shield;
|
||||
int power;
|
||||
int load;
|
||||
int loadLink;
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, unsigned int version)
|
||||
{
|
||||
ar & id & type & pos & angle & speed & energy & shield & power & load & loadLink;
|
||||
}
|
||||
|
||||
static ObjectParams FromObject(CObject* o)
|
||||
{
|
||||
ObjectParams op;
|
||||
op.id = o->GetID();
|
||||
op.type = o->GetType();
|
||||
for(int i = 0; i < OBJECTMAXPART; i++)
|
||||
{
|
||||
op.pos[i] = o->GetPosition(i);
|
||||
op.angle[i] = o->GetAngle(i);
|
||||
}
|
||||
if(o->GetPhysics() != nullptr)
|
||||
op.speed = o->GetPhysics()->GetMotorSpeed();
|
||||
else
|
||||
op.speed = Math::Vector();
|
||||
op.energy = o->GetEnergy();
|
||||
op.shield = o->GetShield();
|
||||
if(o->GetPower() != nullptr)
|
||||
op.power = o->GetPower()->GetID();
|
||||
else
|
||||
op.power = -1;
|
||||
if(o->GetFret() != nullptr)
|
||||
op.load = o->GetFret()->GetID();
|
||||
else
|
||||
op.load = -1;
|
||||
op.loadLink = o->GetTruckPart();
|
||||
return op;
|
||||
}
|
||||
|
||||
bool Apply(bool linkObjects = true)
|
||||
{
|
||||
CObject* obj = CObjectManager::GetInstancePointer()->GetObjectById(id);
|
||||
if(obj == nullptr) return false;
|
||||
for(int i = 0; i < OBJECTMAXPART; i++)
|
||||
{
|
||||
obj->SetPosition(i, pos[i]);
|
||||
obj->SetAngle(i, angle[i]);
|
||||
}
|
||||
if(obj->GetPhysics() != nullptr && !obj->GetSelect())
|
||||
obj->GetPhysics()->SetMotorSpeed(speed);
|
||||
obj->SetEnergy(energy);
|
||||
obj->SetShield(shield);
|
||||
if(linkObjects)
|
||||
LinkObjects();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LinkObjects()
|
||||
{
|
||||
CObjectManager* objman = CObjectManager::GetInstancePointer();
|
||||
CObject* obj = objman->GetObjectById(id);
|
||||
|
||||
CObject* old_power = obj->GetPower();
|
||||
CObject* new_power = power < 0 ? nullptr : objman->GetObjectById(power);
|
||||
if(old_power != new_power)
|
||||
{
|
||||
if(old_power != nullptr) {
|
||||
old_power->SetTruck(nullptr);
|
||||
}
|
||||
obj->SetPower(new_power);
|
||||
if(new_power != nullptr) {
|
||||
new_power->SetTruck(obj);
|
||||
}
|
||||
}
|
||||
|
||||
CObject* old_load = obj->GetFret();
|
||||
CObject* new_load = load < 0 ? nullptr : objman->GetObjectById(load);
|
||||
if(old_load != new_load)
|
||||
{
|
||||
if(old_load != nullptr) {
|
||||
old_load->SetTruck(nullptr);
|
||||
}
|
||||
obj->SetFret(new_load);
|
||||
if(new_load != nullptr) {
|
||||
new_load->SetTruck(obj);
|
||||
}
|
||||
}
|
||||
|
||||
obj->SetTruckPart(loadLink);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//! Packet magic identifier - try to guess what this value means ;)
|
||||
static const uint32_t PACKET_MAGIC = 0x444c4f47;
|
||||
|
||||
enum PacketType {
|
||||
PACKET_S_HANDSHAKE, // [S] Hello, this is server '%s' and we're running map '%s' on version '%s'. Do you want to connect? (disconnect now if you only wanted info to display in server list)
|
||||
PACKET_C_CONNECT, // [C] Hi, I'm '%s' and I'd like to connect. This (is|isn't) a local game.
|
||||
PACKET_S_LEVEL_DATA, // [S] (a set of CreateObject instructions)
|
||||
PACKET_C_MAP_LOADED, // (*) [C] OK, level is loaded
|
||||
PACKET_S_JOINED, // (*) [S] Welcome on the server! (broadcast to all players)
|
||||
|
||||
PACKET_C_OBJECT_UPDATE, // [C] I've updated an object
|
||||
PACKET_S_OBJECT_UPDATE, // [S] Object %d has been updated. It's now at position ..., angle ..., and it's velocity is ...
|
||||
|
||||
PACKET_C_TASK_START, // (*) [C] Start task ...
|
||||
PACKET_S_TASK_START, // (*) [S] Task ... has been started on object ...
|
||||
PACKET_S_TASK_UPDATE, // (*) [S] Task has been updated
|
||||
PACKET_C_TASK_ABORT, // (*) [C] Abort task ...
|
||||
PACKET_S_TASK_ABORT, // (*) [S] Task ... has been aborted,
|
||||
|
||||
PACKET_C_CBOT_SCRIPT, // (*) [C] I've edited the script
|
||||
PACKET_S_CBOT_SCRIPT, // (*) [S] The script has been edited
|
||||
PACKET_C_CBOT_STARTSTOP, // (*) [C] Start/stop the script (see params)
|
||||
PACKET_S_CBOT_STARTSTOP, // (*) [S] The script has been started/stopped (updates blinking lights etc., DOESN'T start the script clientside)
|
||||
|
||||
PACKET_C_DISCONNECT, // [C] I'm disconnecting, bye
|
||||
PACKET_S_DISCONNECT, // [S] You are a cheater, I'm disconnecting you! (or the server is just shutting down... :P)
|
||||
PACKET_S_DISCONNECT_NOTIFY, // [S] %s has disconnected
|
||||
};
|
||||
|
||||
struct PacketHeader {
|
||||
//! Packet magic number
|
||||
uint32_t magic;
|
||||
//! Packet type
|
||||
PacketType type;
|
||||
//! Size of additional packet data (after the header)
|
||||
uint32_t len;
|
||||
} __attribute__((__packed__));
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, Math::Vector& o, const unsigned int version) {
|
||||
ar & o.x & o.y & o.z;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "net/services/client.h"
|
||||
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include "net/connections/connclient.h"
|
||||
|
||||
#include "object/robotmain.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
|
||||
|
||||
CClient::CClient(std::string server) : CNetworkService(), m_resolver(m_service), m_connection(nullptr)
|
||||
{
|
||||
Connect(server);
|
||||
StartIOThread();
|
||||
m_updateTimer = UPDATE_INTERVAL;
|
||||
m_lastPower = nullptr;
|
||||
m_lastLoad = nullptr;
|
||||
}
|
||||
|
||||
void CClient::Stop()
|
||||
{
|
||||
m_connection->Send(PACKET_C_DISCONNECT);
|
||||
m_connection->GetSocket().cancel();
|
||||
StopIOThread();
|
||||
}
|
||||
|
||||
CClientConnection* CClient::GetConnection()
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void CClient::Connect(std::string server)
|
||||
{
|
||||
tcp::resolver::query query(server, boost::lexical_cast<std::string>(PORT));
|
||||
m_resolver.async_resolve(query, boost::bind(&CClient::HandleResolve, this, boost::asio::placeholders::error, boost::asio::placeholders::iterator));
|
||||
}
|
||||
|
||||
void CClient::HandleResolve(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator)
|
||||
{
|
||||
if (!err)
|
||||
{
|
||||
m_connection = new CClientConnection(m_resolver.get_io_service(), this);
|
||||
// Try to connect to first endpoint in the list
|
||||
tcp::endpoint endpoint = *endpoint_iterator;
|
||||
m_connection->GetSocket().async_connect(endpoint, boost::bind(&CClient::HandleConnect, this, boost::asio::placeholders::error, ++endpoint_iterator));
|
||||
} else {
|
||||
CLogger::GetInstancePointer()->Error("Failed to resolve hostname: %s\n", err.message().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::HandleConnect(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator)
|
||||
{
|
||||
if (!err)
|
||||
{
|
||||
// The connection was successful
|
||||
m_connection->Init();
|
||||
}
|
||||
else if (endpoint_iterator != tcp::resolver::iterator())
|
||||
{
|
||||
// The connection failed. Try the next endpoint in the list
|
||||
m_connection->GetSocket().close();
|
||||
tcp::endpoint endpoint = *endpoint_iterator;
|
||||
m_connection->GetSocket().async_connect(endpoint, boost::bind(&CClient::HandleConnect, this, boost::asio::placeholders::error, ++endpoint_iterator));
|
||||
} else {
|
||||
// The connection failed on all endpoints, report an error
|
||||
CLogger::GetInstancePointer()->Error("Failed to connect: %s\n", err.message().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::ProcessEvent(Event& event)
|
||||
{
|
||||
if(event.type == EVENT_FRAME)
|
||||
{
|
||||
m_updateTimer -= event.rTime;
|
||||
if(m_updateTimer <= 0.0f)
|
||||
{
|
||||
m_updateTimer += UPDATE_INTERVAL;
|
||||
SendObjectUpdate();
|
||||
}
|
||||
|
||||
if(m_connection != nullptr)
|
||||
{
|
||||
m_connection->EventUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CClient::SendObjectUpdate()
|
||||
{
|
||||
if(m_connection == nullptr) return;
|
||||
std::ostringstream so;
|
||||
boost::archive::text_oarchive ar_out(so);
|
||||
std::vector<ObjectParams> objects;
|
||||
|
||||
CObject* o = CRobotMain::GetInstancePointer()->GetSelect();
|
||||
if(o == nullptr) return;
|
||||
ObjectParams op = ObjectParams::FromObject(o);
|
||||
objects.push_back(op);
|
||||
|
||||
CObject* power = o->GetPower();
|
||||
if(power != nullptr)
|
||||
{
|
||||
ObjectParams op_power = ObjectParams::FromObject(power);
|
||||
objects.push_back(op_power);
|
||||
}
|
||||
if(power != m_lastPower)
|
||||
{
|
||||
if(m_lastPower != nullptr)
|
||||
{
|
||||
ObjectParams op_power = ObjectParams::FromObject(m_lastPower);
|
||||
objects.push_back(op_power);
|
||||
if(m_lastPower->GetTruck() != nullptr && m_lastPower->GetTruck() != o) {
|
||||
ObjectParams op_truck = ObjectParams::FromObject(m_lastPower->GetTruck());
|
||||
objects.push_back(op_truck);
|
||||
}
|
||||
}
|
||||
m_lastPower = power;
|
||||
}
|
||||
|
||||
CObject* load = o->GetFret();
|
||||
if(load != nullptr)
|
||||
{
|
||||
ObjectParams op_load = ObjectParams::FromObject(load);
|
||||
objects.push_back(op_load);
|
||||
}
|
||||
if(load != m_lastLoad)
|
||||
{
|
||||
if(m_lastLoad != nullptr)
|
||||
{
|
||||
ObjectParams op_load = ObjectParams::FromObject(m_lastLoad);
|
||||
objects.push_back(op_load);
|
||||
if(m_lastLoad->GetTruck() != nullptr && m_lastLoad->GetTruck() != o) {
|
||||
ObjectParams op_truck = ObjectParams::FromObject(m_lastPower->GetTruck());
|
||||
objects.push_back(op_truck);
|
||||
}
|
||||
}
|
||||
m_lastLoad = load;
|
||||
}
|
||||
|
||||
ar_out & objects;
|
||||
|
||||
m_connection->Send(PACKET_C_OBJECT_UPDATE, so.str());
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/services/netservice.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
class CClientConnection;
|
||||
class CController;
|
||||
class CObject;
|
||||
|
||||
class CClient : public CNetworkService {
|
||||
friend class CClientConnection;
|
||||
friend class CController;
|
||||
const float UPDATE_INTERVAL = 1.0f/30.0f;
|
||||
public:
|
||||
CClient(std::string server);
|
||||
void Stop();
|
||||
|
||||
CClientConnection* GetConnection();
|
||||
|
||||
void ProcessEvent(Event& event);
|
||||
|
||||
private:
|
||||
void Connect(std::string server);
|
||||
void HandleResolve(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator);
|
||||
void HandleConnect(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator);
|
||||
|
||||
void SendObjectUpdate();
|
||||
|
||||
private:
|
||||
tcp::resolver m_resolver;
|
||||
CClientConnection* m_connection;
|
||||
float m_updateTimer;
|
||||
|
||||
CObject* m_lastPower;
|
||||
CObject* m_lastLoad;
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "net/services/netservice.h"
|
||||
|
||||
CNetworkService::CNetworkService()
|
||||
{
|
||||
m_thread = nullptr;
|
||||
}
|
||||
|
||||
CNetworkService::~CNetworkService()
|
||||
{
|
||||
if(m_thread != nullptr) {
|
||||
StopIOThread();
|
||||
}
|
||||
}
|
||||
|
||||
void CNetworkService::StartIOThread()
|
||||
{
|
||||
assert(m_thread == nullptr);
|
||||
m_thread = new boost::thread(boost::bind(&boost::asio::io_service::run, &m_service));
|
||||
}
|
||||
|
||||
void CNetworkService::StopIOThread()
|
||||
{
|
||||
m_service.stop();
|
||||
m_thread->join(); //TODO: try to remove this
|
||||
m_thread = nullptr;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/event.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
class CNetworkService {
|
||||
public:
|
||||
const int PORT = 1234;
|
||||
|
||||
CNetworkService();
|
||||
virtual ~CNetworkService();
|
||||
|
||||
virtual void ProcessEvent(Event& event) = 0;
|
||||
|
||||
protected:
|
||||
void StartIOThread();
|
||||
void StopIOThread();
|
||||
|
||||
protected:
|
||||
boost::asio::io_service m_service;
|
||||
boost::thread* m_thread;
|
||||
};
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#include "net/services/server.h"
|
||||
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include "net/connections/connserver.h"
|
||||
#include "net/packets/objectparams.h"
|
||||
#include "net/packets/packettype.h"
|
||||
|
||||
#include "object/objman.h"
|
||||
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/serialization/string.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
|
||||
|
||||
CServer::CServer() : CNetworkService(), m_acceptor(m_service, tcp::endpoint(tcp::v4(), PORT))
|
||||
{
|
||||
StartAccept();
|
||||
StartIOThread();
|
||||
m_updateTimer = UPDATE_INTERVAL;
|
||||
}
|
||||
|
||||
void CServer::Stop()
|
||||
{
|
||||
Broadcast(PACKET_S_DISCONNECT);
|
||||
for(auto connection : m_connections)
|
||||
{
|
||||
connection->GetSocket().cancel();
|
||||
}
|
||||
StopIOThread();
|
||||
}
|
||||
|
||||
void CServer::Broadcast(PacketType packet, std::string data)
|
||||
{
|
||||
for(auto connection : m_connections)
|
||||
{
|
||||
connection->Send(packet, data);
|
||||
}
|
||||
}
|
||||
|
||||
void CServer::StartAccept()
|
||||
{
|
||||
CServerConnection* new_connection = new CServerConnection(m_acceptor.get_io_service(), this);
|
||||
|
||||
m_acceptor.async_accept(new_connection->GetSocket(), boost::bind(&CServer::HandleAccept, this, new_connection, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void CServer::HandleAccept(CServerConnection* new_connection, const boost::system::error_code& err)
|
||||
{
|
||||
if(!err)
|
||||
{
|
||||
m_connections.push_back(new_connection);
|
||||
new_connection->Init();
|
||||
} else {
|
||||
CLogger::GetInstancePointer()->Warn("Failed to accept connection: %s\n", err.message().c_str());
|
||||
}
|
||||
StartAccept();
|
||||
}
|
||||
|
||||
void CServer::ProcessEvent(Event& event)
|
||||
{
|
||||
if(event.type == EVENT_FRAME)
|
||||
{
|
||||
m_updateTimer -= event.rTime;
|
||||
if(m_updateTimer <= 0.0f)
|
||||
{
|
||||
m_updateTimer += UPDATE_INTERVAL;
|
||||
SendObjectsUpdate();
|
||||
}
|
||||
|
||||
for(auto connection : m_connections)
|
||||
{
|
||||
connection->EventUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CServer::SendObjectsUpdate()
|
||||
{
|
||||
std::ostringstream so;
|
||||
boost::archive::text_oarchive ar_out(so);
|
||||
|
||||
std::vector<ObjectParams> objects;
|
||||
|
||||
for(auto it : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
{
|
||||
CObject* o = it.second;
|
||||
ObjectType type = o->GetType();
|
||||
//TODO: We need a function to tell us if this is a stationary object
|
||||
if(type == OBJECT_PLANT0 ||
|
||||
type == OBJECT_PLANT1 ||
|
||||
type == OBJECT_PLANT2 ||
|
||||
type == OBJECT_PLANT3 ||
|
||||
type == OBJECT_PLANT4 ||
|
||||
type == OBJECT_PLANT5 ||
|
||||
type == OBJECT_PLANT6 ||
|
||||
type == OBJECT_PLANT7 ||
|
||||
type == OBJECT_PLANT8 ||
|
||||
type == OBJECT_PLANT9 ||
|
||||
type == OBJECT_PLANT10 ||
|
||||
type == OBJECT_PLANT11 ||
|
||||
type == OBJECT_PLANT12 ||
|
||||
type == OBJECT_PLANT13 ||
|
||||
type == OBJECT_PLANT14 ||
|
||||
type == OBJECT_PLANT15 ||
|
||||
type == OBJECT_PLANT16 ||
|
||||
type == OBJECT_PLANT17 ||
|
||||
type == OBJECT_PLANT18 ||
|
||||
type == OBJECT_PLANT19 ||
|
||||
type == OBJECT_TREE0 ||
|
||||
type == OBJECT_TREE1 ||
|
||||
type == OBJECT_TREE2 ||
|
||||
type == OBJECT_TREE3 ||
|
||||
type == OBJECT_TREE4 ||
|
||||
type == OBJECT_TREE5 ||
|
||||
type == OBJECT_BARRIER0 ||
|
||||
type == OBJECT_BARRIER1 ||
|
||||
type == OBJECT_BARRIER2 ||
|
||||
type == OBJECT_BARRIER3 ||
|
||||
type == OBJECT_RUINmobilew1 ||
|
||||
type == OBJECT_RUINmobilew2 ||
|
||||
type == OBJECT_RUINmobilet1 ||
|
||||
type == OBJECT_RUINmobilet2 ||
|
||||
type == OBJECT_RUINmobiler1 ||
|
||||
type == OBJECT_RUINmobiler2 ||
|
||||
type == OBJECT_RUINfactory ||
|
||||
type == OBJECT_RUINdoor ||
|
||||
type == OBJECT_RUINsupport ||
|
||||
type == OBJECT_RUINradar ||
|
||||
type == OBJECT_RUINconvert ||
|
||||
type == OBJECT_RUINbase ||
|
||||
type == OBJECT_RUINhead ||
|
||||
type == OBJECT_TEEN0 ||
|
||||
type == OBJECT_TEEN1 ||
|
||||
type == OBJECT_TEEN2 ||
|
||||
type == OBJECT_TEEN3 ||
|
||||
type == OBJECT_TEEN4 ||
|
||||
type == OBJECT_TEEN5 ||
|
||||
type == OBJECT_TEEN6 ||
|
||||
type == OBJECT_TEEN7 ||
|
||||
type == OBJECT_TEEN8 ||
|
||||
type == OBJECT_TEEN9 ||
|
||||
type == OBJECT_TEEN10 ||
|
||||
type == OBJECT_TEEN11 ||
|
||||
type == OBJECT_TEEN12 ||
|
||||
type == OBJECT_TEEN13 ||
|
||||
type == OBJECT_TEEN14 ||
|
||||
type == OBJECT_TEEN15 ||
|
||||
type == OBJECT_TEEN16 ||
|
||||
type == OBJECT_TEEN17 ||
|
||||
type == OBJECT_TEEN18 ||
|
||||
type == OBJECT_TEEN19 ||
|
||||
type == OBJECT_TEEN20 ||
|
||||
type == OBJECT_TEEN21 ||
|
||||
type == OBJECT_TEEN22 ||
|
||||
type == OBJECT_TEEN23 ||
|
||||
type == OBJECT_TEEN24 ||
|
||||
type == OBJECT_TEEN25 ||
|
||||
type == OBJECT_TEEN26 ||
|
||||
type == OBJECT_TEEN27 ||
|
||||
type == OBJECT_TEEN28 ||
|
||||
type == OBJECT_TEEN29 ||
|
||||
type == OBJECT_TEEN30 ||
|
||||
type == OBJECT_TEEN31 ||
|
||||
type == OBJECT_TEEN32 ||
|
||||
type == OBJECT_TEEN33 ||
|
||||
type == OBJECT_TEEN34 ||
|
||||
type == OBJECT_TEEN35 ||
|
||||
type == OBJECT_TEEN36 ||
|
||||
type == OBJECT_TEEN37 ||
|
||||
type == OBJECT_TEEN38 ||
|
||||
type == OBJECT_TEEN39 ||
|
||||
type == OBJECT_TEEN40 ||
|
||||
type == OBJECT_TEEN41 ||
|
||||
type == OBJECT_TEEN42 ||
|
||||
type == OBJECT_TEEN43 ||
|
||||
type == OBJECT_TEEN44 ||
|
||||
type == OBJECT_QUARTZ0 ||
|
||||
type == OBJECT_QUARTZ1 ||
|
||||
type == OBJECT_QUARTZ2 ||
|
||||
type == OBJECT_QUARTZ3 ||
|
||||
type == OBJECT_ROOT0 ||
|
||||
type == OBJECT_ROOT1 ||
|
||||
type == OBJECT_ROOT2 ||
|
||||
type == OBJECT_ROOT3 ||
|
||||
type == OBJECT_ROOT4 ||
|
||||
type == OBJECT_ROOT5 ||
|
||||
type == OBJECT_MUSHROOM1 ||
|
||||
type == OBJECT_MUSHROOM2 ||
|
||||
type == OBJECT_APOLLO1 ||
|
||||
type == OBJECT_APOLLO2 ||
|
||||
type == OBJECT_APOLLO3 ||
|
||||
type == OBJECT_APOLLO4 ||
|
||||
type == OBJECT_APOLLO5 ||
|
||||
type == OBJECT_HOME1) continue;
|
||||
ObjectParams op = ObjectParams::FromObject(o);
|
||||
objects.push_back(op);
|
||||
}
|
||||
ar_out & objects;
|
||||
Broadcast(PACKET_S_OBJECT_UPDATE, so.str());
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* 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 3 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, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/services/netservice.h"
|
||||
|
||||
#include "net/packets/packettype.h"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
class CServerConnection;
|
||||
class CController;
|
||||
|
||||
class CServer : public CNetworkService {
|
||||
friend class CServerConnection;
|
||||
friend class CController;
|
||||
const float UPDATE_INTERVAL = 1.0f/30.0f;
|
||||
public:
|
||||
CServer();
|
||||
void Stop();
|
||||
|
||||
void ProcessEvent(Event& event);
|
||||
|
||||
void Broadcast(PacketType packet, std::string data = "");
|
||||
|
||||
private:
|
||||
void StartAccept();
|
||||
void HandleAccept(CServerConnection* new_connection, const boost::system::error_code& err);
|
||||
|
||||
void SendObjectsUpdate();
|
||||
|
||||
private:
|
||||
tcp::acceptor m_acceptor;
|
||||
std::vector<CServerConnection*> m_connections;
|
||||
float m_updateTimer;
|
||||
};
|
|
@ -66,6 +66,7 @@ bool CObjectManager::DeleteObject(CObject* instance)
|
|||
|
||||
CObject* CObjectManager::GetObjectById(unsigned int id)
|
||||
{
|
||||
if(m_table.find(id) == m_table.end()) return nullptr;
|
||||
return m_table[id];
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "common/misc.h"
|
||||
#include "common/profile.h"
|
||||
#include "common/restext.h"
|
||||
#include "common/windowsfix.h"
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
#include "common/resources/inputstream.h"
|
||||
|
@ -54,6 +55,10 @@
|
|||
#include "math/const.h"
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "net/connections/connclient.h"
|
||||
#include "net/packets/objectparams.h"
|
||||
#include "net/services/client.h"
|
||||
|
||||
#include "object/auto/auto.h"
|
||||
#include "object/auto/autobase.h"
|
||||
#include "object/brain.h"
|
||||
|
@ -3432,8 +3437,24 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
|||
InitEye();
|
||||
SetMovieLock(false);
|
||||
|
||||
if (read[0] != 0) // loading file ?
|
||||
sel = IOReadScene(read, stack);
|
||||
if(!m_ctrl->IsServer())
|
||||
{
|
||||
for(ObjectParams op : m_ctrl->GetClient()->GetConnection()->GetLevelData())
|
||||
{
|
||||
CLogger::GetInstancePointer()->Debug("Received object %d from server\n", op.id); //TODO: Change to Trace later
|
||||
g_id = op.id-1; //TODO: Well, this is a bit hacky solution
|
||||
CObjectManager::GetInstancePointer()->CreateObject(op.pos[0], op.angle[0].y, op.type, -1.0f);
|
||||
op.Apply(false);
|
||||
}
|
||||
|
||||
for(ObjectParams op : m_ctrl->GetClient()->GetConnection()->GetLevelData())
|
||||
{
|
||||
op.LinkObjects();
|
||||
}
|
||||
} else {
|
||||
if (read[0] != 0) // loading file ?
|
||||
sel = IOReadScene(read, stack);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -3456,6 +3477,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
|||
|
||||
if (line->GetCommand() == "CreateObject" && read[0] == 0)
|
||||
{
|
||||
if(!m_ctrl->IsServer()) continue;
|
||||
ObjectType type = line->GetParam("type")->AsObjectType();
|
||||
|
||||
int gadget = line->GetParam("gadget")->AsInt(-1);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "ui/maindialog.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/controller.h"
|
||||
#include "app/input.h"
|
||||
#include "app/system.h"
|
||||
|
||||
|
@ -114,8 +115,9 @@ static int perso_color[3*10*3] =
|
|||
|
||||
// Constructor of robot application.
|
||||
|
||||
CMainDialog::CMainDialog()
|
||||
CMainDialog::CMainDialog(CController* controller)
|
||||
{
|
||||
m_controller = controller;
|
||||
m_app = nullptr;
|
||||
m_eventQueue = nullptr;
|
||||
m_sound = nullptr;
|
||||
|
@ -189,10 +191,10 @@ CMainDialog::CMainDialog()
|
|||
|
||||
void CMainDialog::Create()
|
||||
{
|
||||
m_app = CApplication::GetInstancePointer();
|
||||
m_app = m_controller->GetApplication();
|
||||
m_eventQueue = m_app->GetEventQueue();
|
||||
m_sound = m_app->GetSound();
|
||||
m_main = CRobotMain::GetInstancePointer();
|
||||
m_main = m_controller->GetRobotMain();
|
||||
m_interface = m_main->GetInterface();
|
||||
m_camera = m_main->GetCamera();
|
||||
m_engine = Gfx::CEngine::GetInstancePointer();
|
||||
|
@ -2259,9 +2261,8 @@ bool CMainDialog::EventProcess(const Event &event)
|
|||
break;
|
||||
|
||||
case EVENT_INTERFACE_PLAY:
|
||||
m_sceneRank = (m_chap[m_index]+1)*100+(m_sel[m_index]+1);
|
||||
m_phaseTerm = m_phase;
|
||||
m_main->ChangePhase(PHASE_LOADING);
|
||||
m_controller->StartSP(m_sceneName, m_chap[m_index]+1, m_sel[m_index]+1);
|
||||
break;
|
||||
|
||||
case EVENT_INTERFACE_READ:
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <vector>
|
||||
|
||||
|
||||
class CController;
|
||||
class CEventQueue;
|
||||
class CSoundInterface;
|
||||
|
||||
|
@ -70,7 +71,7 @@ struct GamerPerso
|
|||
class CMainDialog
|
||||
{
|
||||
public:
|
||||
CMainDialog();
|
||||
CMainDialog(CController* controller);
|
||||
~CMainDialog();
|
||||
|
||||
void Create();
|
||||
|
@ -182,6 +183,7 @@ protected:
|
|||
void ChangeKey(EventType event);
|
||||
|
||||
protected:
|
||||
CController* m_controller;
|
||||
CApplication* m_app;
|
||||
CRobotMain* m_main;
|
||||
CEventQueue* m_eventQueue;
|
||||
|
|
Loading…
Reference in New Issue