mirror of
https://github.com/SWG-Source/src.git
synced 2026-07-28 22:15:49 -04:00
Added serverUtility library
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
|
||||
add_subdirectory(serverKeyShare)
|
||||
add_subdirectory(serverMetrics)
|
||||
add_subdirectory(serverUtility)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(serverUtility)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public)
|
||||
|
||||
add_subdirectory(src)
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/AdminAccountManager.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ChatLogManager.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ClusterWideDataManager.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ClusterWideDataManagerList.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ConfigServerUtility.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/FirstServerUtility.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/FreeCtsDataTable.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/LocationData.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/MissionLocation.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/PopulationList.h"
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "../../src/shared/PvpEnemy.h"
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
#include "../../src/shared/RecentMaxSyncedValue.h"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ResourceFractalData.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ServerClock.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ServerConnection.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/ServerServiceHandler.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/SetupServerUtility.h"
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
set(SHARED_SOURCES
|
||||
shared/AdminAccountManager.cpp
|
||||
shared/AdminAccountManager.h
|
||||
shared/ChatLogManager.cpp
|
||||
shared/ConfigServerUtility.cpp
|
||||
shared/ConfigServerUtility.h
|
||||
shared/ClusterWideDataManager.cpp
|
||||
shared/ClusterWideDataManager.h
|
||||
shared/ClusterWideDataManagerList.cpp
|
||||
shared/ClusterWideDataManagerList.h
|
||||
shared/FirstServerUtility.h
|
||||
shared/FreeCtsDataTable.cpp
|
||||
shared/FreeCtsDataTable.h
|
||||
shared/LocationData.cpp
|
||||
shared/LocationData.h
|
||||
shared/MissionLocation.cpp
|
||||
shared/MissionLocation.h
|
||||
shared/PopulationList.cpp
|
||||
shared/PopulationList.h
|
||||
shared/PvpEnemy.cpp
|
||||
shared/PvpEnemy.h
|
||||
shared/ResourceFractalData.cpp
|
||||
shared/ResourceFractalData.h
|
||||
shared/RecentMaxSyncedValue.cpp
|
||||
shared/RecentMaxSyncedValue.h
|
||||
shared/ServerClock.cpp
|
||||
shared/ServerClock.h
|
||||
shared/ServerConnection.cpp
|
||||
shared/ServerConnection.h
|
||||
shared/ServerServiceHandler.h
|
||||
shared/SetupServerUtility.cpp
|
||||
shared/SetupServerUtility.h
|
||||
shared/SystemAssignedProcessId.cpp
|
||||
shared/SystemAssignedProcessId.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
win32/FirstServerUtility.cpp
|
||||
)
|
||||
else()
|
||||
set(PLATFORM_SOURCES
|
||||
linux/stlhack.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetwork/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/serverNetworkMessages/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
|
||||
)
|
||||
|
||||
add_library(serverUtility STATIC
|
||||
${SHARED_SOURCES}
|
||||
${PLATFORM_SOURCES}
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
//#include "FirstGame.h"
|
||||
#include <hash_map> //without this we get an internal compiler error
|
||||
|
||||
// This resolves a problem with stlport compiling under gcc 2.91 that ships with RedHat 6.2.
|
||||
// Basically, the compiler has trouble instantiating an instance of _Stl_prime<bool> without it
|
||||
// being explicitly defined. So we have to instantiate one.
|
||||
// We should try removing this file when either we a) upgrade the compiler or b) upgrate the OS.
|
||||
|
||||
#define __stl_num_primes 28
|
||||
#define __PRIME_LIST_BODY { \
|
||||
53ul, 97ul, 193ul, 389ul, 769ul, \
|
||||
1543ul, 3079ul, 6151ul, 12289ul, 24593ul, \
|
||||
49157ul, 98317ul, 196613ul, 393241ul, 786433ul, \
|
||||
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, \
|
||||
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,\
|
||||
1610612741ul, 3221225473ul, 4294967291ul \
|
||||
}
|
||||
|
||||
template <> const size_t std::_Stl_prime<bool>::_M_list[__stl_num_primes] = __PRIME_LIST_BODY;
|
||||
|
||||
#undef __stl_num_primes
|
||||
#undef __PRIME_LIST_BODY
|
||||
@@ -0,0 +1,139 @@
|
||||
// AdminAccountManager.cpp
|
||||
// copyright 2002 Sony Online Entertainment
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/AdminAccountManager.h"
|
||||
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedUtility/DataTable.h"
|
||||
#include "sharedUtility/DataTableManager.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
DataTable * AdminAccountManager::ms_adminTable = 0;
|
||||
bool AdminAccountManager::ms_installed = false;
|
||||
std::string *AdminAccountManager::ms_dataTableName = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void AdminAccountManager::install(const std::string &dataTableName)
|
||||
{
|
||||
DEBUG_FATAL(ms_installed, ("AdminAccountManager already installed"));
|
||||
|
||||
ms_adminTable = DataTableManager::getTable (dataTableName, true);
|
||||
DEBUG_FATAL(!ms_adminTable, ("Could not open admin file %s!", dataTableName.c_str()));
|
||||
ms_installed = true;
|
||||
|
||||
ms_dataTableName = new std::string(dataTableName);
|
||||
|
||||
ExitChain::add(AdminAccountManager::remove, "DataTableManager::remove");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void AdminAccountManager::remove()
|
||||
{
|
||||
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
|
||||
NOT_NULL(ms_dataTableName);
|
||||
DataTableManager::close(*ms_dataTableName);
|
||||
ms_installed = false;
|
||||
delete ms_dataTableName;
|
||||
ms_dataTableName = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const char *AdminAccountManager::getAdminCommandName()
|
||||
{
|
||||
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
|
||||
return ms_adminTable->getStringValue("AdminSkill", 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const std::string & AdminAccountManager::getAdminTagName()
|
||||
{
|
||||
static const std::string s = "*admin*";
|
||||
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
|
||||
return s;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool AdminAccountManager::isAdminAccount(const std::string & account, int& level)
|
||||
{
|
||||
level = 0;
|
||||
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
|
||||
|
||||
int columnNumber = ms_adminTable->findColumnNumber("AdminAccounts");
|
||||
DEBUG_FATAL(columnNumber == -1, ("Error loading admin table...no account column"));
|
||||
int row = ms_adminTable->searchColumnString( columnNumber, account);
|
||||
if (row == -1)
|
||||
return false;
|
||||
|
||||
level = ms_adminTable->getIntValue("AdminLevel", row);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool AdminAccountManager::isInternalIp(const std::string & addr)
|
||||
{
|
||||
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
|
||||
|
||||
std::vector<const char *> ipAddrs;
|
||||
ms_adminTable->getStringColumn("AdminIpBlocks", ipAddrs);
|
||||
|
||||
bool retval = false;
|
||||
|
||||
for (std::vector<const char *>::iterator i = ipAddrs.begin(); i != ipAddrs.end(); ++i)
|
||||
{
|
||||
const std::string ipAddr(*i);
|
||||
|
||||
//Check IP block
|
||||
//Look for X in the IP block signifying a wild card.
|
||||
size_t xpos = ipAddr.find ('x');
|
||||
|
||||
//if no X is found, do a straight compare
|
||||
if ( (xpos == 0 || xpos == std::string::npos)
|
||||
&& ipAddr.compare(addr) == 0
|
||||
)
|
||||
{
|
||||
retval = true;
|
||||
}
|
||||
|
||||
//we only want to compare up to the X, but if that is bigger that our addr
|
||||
//we cannot compare the two, so return false.
|
||||
else if (xpos - 1 > addr.size())
|
||||
retval = false;
|
||||
|
||||
//compare substring
|
||||
else if (ipAddr.compare(0, xpos - 1, addr, 0, xpos - 1) == 0)
|
||||
{
|
||||
retval = true;
|
||||
}
|
||||
|
||||
if (retval == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void AdminAccountManager::reload()
|
||||
{
|
||||
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
|
||||
NOT_NULL(ms_dataTableName);
|
||||
DataTableManager::reload(*ms_dataTableName);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,40 @@
|
||||
// AdminAccountManager.h
|
||||
// copyright 2002 Sony Online Entertainment
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _AdminAccountManager_H
|
||||
#define _AdminAccountManager_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class DataTable;
|
||||
|
||||
class AdminAccountManager
|
||||
{
|
||||
|
||||
public:
|
||||
static void install(const std::string &dataTableName);
|
||||
static void remove();
|
||||
|
||||
static const char *getAdminCommandName();
|
||||
static const std::string & getAdminTagName();
|
||||
|
||||
static bool isAdminAccount(const std::string & account, int& level);
|
||||
static bool isInternalIp(const std::string & addr);
|
||||
static void reload();
|
||||
|
||||
|
||||
private:
|
||||
AdminAccountManager();
|
||||
~AdminAccountManager();
|
||||
|
||||
static DataTable * ms_adminTable;
|
||||
static bool ms_installed;
|
||||
static std::string * ms_dataTableName;
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,489 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// ChatLogManager.cpp
|
||||
// Copyright Sony Online Entertainment, Inc.
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/ChatLogManager.h"
|
||||
|
||||
#include "serverUtility/ConfigServerUtility.h"
|
||||
#include "sharedFoundation/LessPointerComparator.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/FormattedString.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include "sharedNetworkMessages/ChatAvatarId.h"
|
||||
#include "sharedNetworkMessages/MessageQueueSpatialChat.h"
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ChatLogManagerNamespace
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
namespace ChatLogManagerNamespace
|
||||
{
|
||||
class ChatLogEntry
|
||||
{
|
||||
public:
|
||||
|
||||
ChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const *text, Unicode::String const &channel, time_t const time)
|
||||
: m_fromPlayer(Unicode::toLower(fromPlayer))
|
||||
, m_toPlayer(Unicode::toLower(toPlayer))
|
||||
, m_text(text)
|
||||
, m_channel(channel)
|
||||
, m_time(time)
|
||||
{
|
||||
}
|
||||
|
||||
Unicode::String const &getFromPlayer() const
|
||||
{
|
||||
return m_fromPlayer;
|
||||
}
|
||||
|
||||
Unicode::String const &getToPlayer() const
|
||||
{
|
||||
return m_toPlayer;
|
||||
}
|
||||
|
||||
Unicode::String const &getText() const
|
||||
{
|
||||
return *m_text;
|
||||
}
|
||||
|
||||
Unicode::String const &getChannel() const
|
||||
{
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
time_t getTime() const
|
||||
{
|
||||
return m_time;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Unicode::String m_fromPlayer;
|
||||
Unicode::String m_toPlayer;
|
||||
Unicode::String const *m_text;
|
||||
Unicode::String m_channel;
|
||||
time_t m_time;
|
||||
|
||||
// Disabled
|
||||
|
||||
ChatLogEntry();
|
||||
};
|
||||
|
||||
typedef std::list<std::pair<time_t, int> > TimeLog;
|
||||
typedef std::map<int, ChatLogEntry> ChatLog;
|
||||
typedef std::map<Unicode::String, int> PlayerLog;
|
||||
typedef std::map<Unicode::String const *, int, LessPointerComparator> MessageList; // Second parameter is the reference count
|
||||
|
||||
TimeLog s_timeLog;
|
||||
ChatLog s_chatLog;
|
||||
PlayerLog s_playerLog;
|
||||
MessageList s_chatMessageList;
|
||||
time_t s_purgeTime = 0;
|
||||
int s_currentIndex = 0;
|
||||
time_t s_chatLogMemoryTimer = 0;
|
||||
time_t const s_chatLogMemoryTime = 30;
|
||||
int s_cacheHits = 0;
|
||||
int s_cacheMisses = 0;
|
||||
|
||||
void printPlayerLog();
|
||||
void addChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, time_t const time);
|
||||
bool removeChatLogEntry(int const messageIndex);
|
||||
void purgeChatLog();
|
||||
std::string getTimeString(time_t const time);
|
||||
std::string getTimeStringShort(time_t const time);
|
||||
};
|
||||
|
||||
using namespace ChatLogManagerNamespace;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManagerNamespace::printPlayerLog()
|
||||
{
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("-- ChatLogManagerNamespace::printPlayerLog() BEGIN -------------\n"));
|
||||
PlayerLog::const_iterator iterPlayerLog = s_playerLog.begin();
|
||||
|
||||
for (; iterPlayerLog != s_playerLog.end(); ++iterPlayerLog)
|
||||
{
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("player(%s) messages(%d)\n", Unicode::wideToNarrow(iterPlayerLog->first).c_str(), iterPlayerLog->second));
|
||||
}
|
||||
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("-- ChatLogManagerNamespace::printPlayerLog() END -------------\n"));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManagerNamespace::addChatLogEntry(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, time_t const time)
|
||||
{
|
||||
ChatLog::const_iterator iterChatLog = s_chatLog.find(messageIndex);
|
||||
|
||||
if (iterChatLog != s_chatLog.end())
|
||||
{
|
||||
// This string has already been added
|
||||
|
||||
++s_cacheHits;
|
||||
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("INSERT-HIT s_chatLog.size(%u) messageIndex(%d) time(%u) fromPlayer(%s) toPlayer(%s) channel(%s) text(%s)\n", s_chatLog.size(), messageIndex, iterChatLog->second.getTime(), Unicode::wideToNarrow(fromPlayer).c_str(), Unicode::wideToNarrow(toPlayer).c_str(), Unicode::wideToNarrow(channel).c_str(), Unicode::wideToNarrow(message).c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Unicode::String const *finalMessage = NULL;
|
||||
|
||||
// Add the new string to the master message list, or if it already exists, just increase the reference count
|
||||
|
||||
MessageList::iterator iterChatMessageList = s_chatMessageList.find(&message);
|
||||
|
||||
if (iterChatMessageList != s_chatMessageList.end())
|
||||
{
|
||||
// Increase the reference count
|
||||
|
||||
++iterChatMessageList->second;
|
||||
|
||||
finalMessage = iterChatMessageList->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the new message to the list
|
||||
|
||||
finalMessage = new Unicode::String(message);
|
||||
|
||||
s_chatMessageList.insert(std::make_pair(finalMessage, 1));
|
||||
}
|
||||
|
||||
++s_cacheMisses;
|
||||
|
||||
s_timeLog.push_back(std::make_pair(time, messageIndex));
|
||||
s_chatLog.insert(std::make_pair(messageIndex, ChatLogEntry(fromPlayer, toPlayer, finalMessage, channel, time)));
|
||||
|
||||
// Track the player's who are in the logs, and how many time they have messages in the logs
|
||||
|
||||
Unicode::String const lowerFromPlayer(Unicode::toLower(fromPlayer));
|
||||
PlayerLog::iterator iterPlayerLog = s_playerLog.find(lowerFromPlayer);
|
||||
|
||||
if (iterPlayerLog != s_playerLog.end())
|
||||
{
|
||||
++(iterPlayerLog->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_playerLog.insert(std::make_pair(lowerFromPlayer, 1));
|
||||
}
|
||||
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("INSERT-MISS s_chatLog.size(%u) messageIndex(%d) time(%u) fromPlayer(%s) toPlayer(%s) channel(%s) text(%s)\n", s_chatLog.size(), messageIndex, time, Unicode::wideToNarrow(lowerFromPlayer).c_str(), Unicode::wideToNarrow(toPlayer).c_str(), Unicode::wideToNarrow(channel).c_str(), Unicode::wideToNarrow(message).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ChatLogManagerNamespace::removeChatLogEntry(int const messageIndex)
|
||||
{
|
||||
bool result = false;
|
||||
ChatLog::iterator iterChatLog = s_chatLog.find(messageIndex);
|
||||
|
||||
if (iterChatLog != s_chatLog.end())
|
||||
{
|
||||
result = true;
|
||||
|
||||
// Remove the chat message
|
||||
|
||||
Unicode::String const &message = iterChatLog->second.getText();
|
||||
MessageList::iterator iterChatMessageList = s_chatMessageList.find(&message);
|
||||
|
||||
if (iterChatMessageList != s_chatMessageList.end())
|
||||
{
|
||||
if (--iterChatMessageList->second <= 0)
|
||||
{
|
||||
// No more chat logs are referencing this message, we can remove it
|
||||
|
||||
delete iterChatMessageList->first;
|
||||
|
||||
s_chatMessageList.erase(iterChatMessageList);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WARNING(true, ("Master chat list does not contain message index(%d). This is a bug.", messageIndex));
|
||||
}
|
||||
|
||||
// Remove the player log
|
||||
|
||||
PlayerLog::iterator iterPlayerLog = s_playerLog.find(iterChatLog->second.getFromPlayer());
|
||||
|
||||
if (iterPlayerLog != s_playerLog.end())
|
||||
{
|
||||
if (--iterPlayerLog->second <= 0)
|
||||
{
|
||||
s_playerLog.erase(iterPlayerLog);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WARNING(true, ("A player log was unable to be removed for %s", Unicode::wideToNarrow(iterChatLog->second.getFromPlayer()).c_str()));
|
||||
}
|
||||
|
||||
s_chatLog.erase(iterChatLog);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManagerNamespace::purgeChatLog()
|
||||
{
|
||||
// This purges the list of old data once a second
|
||||
|
||||
time_t const systemTime = Os::getRealSystemTime();
|
||||
|
||||
if (s_purgeTime != systemTime)
|
||||
{
|
||||
s_purgeTime = systemTime;
|
||||
|
||||
time_t const chatLogPurgeTime = static_cast<time_t>(ConfigServerUtility::getChatLogMinutes() * 60);
|
||||
TimeLog::iterator iterTimeLog = s_timeLog.begin();
|
||||
int chatLogCount = static_cast<int>(s_timeLog.size());
|
||||
int purgedMessages = 0;
|
||||
|
||||
for (; iterTimeLog != s_timeLog.end(); ++iterTimeLog)
|
||||
{
|
||||
time_t const time = iterTimeLog->first;
|
||||
|
||||
if ( (time < (systemTime - chatLogPurgeTime))
|
||||
|| (static_cast<int>(s_chatMessageList.size()) > ConfigServerUtility::getServerMaxChatLogLines()))
|
||||
{
|
||||
int const messageIndex = iterTimeLog->second;
|
||||
|
||||
if (removeChatLogEntry(messageIndex))
|
||||
{
|
||||
--chatLogCount;
|
||||
++purgedMessages;
|
||||
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("REMOVE index(%d) s_chatLog.size(%u) s_chatMessageList.size(%u)\n", messageIndex, s_chatLog.size(), s_chatMessageList.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("ERROR: REMOVE index(%d) Unable to resolve the message index in the chat log.\n", messageIndex));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (purgedMessages > 0)
|
||||
{
|
||||
// Remove the items from the time log
|
||||
|
||||
s_timeLog.erase(s_timeLog.begin(), iterTimeLog);
|
||||
}
|
||||
|
||||
// Make sure the time log and chat log are equal in size, if not, then something is seriously wrong
|
||||
|
||||
DEBUG_WARNING((s_timeLog.size() != s_chatLog.size()), ("ERROR: Time log and chat log are not the same size. This is a bug."));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string ChatLogManagerNamespace::getTimeString(time_t const time)
|
||||
{
|
||||
std::string result(ctime(&time));
|
||||
|
||||
if (!result.empty())
|
||||
{
|
||||
result.erase(result.size() - 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string ChatLogManagerNamespace::getTimeStringShort(time_t const time)
|
||||
{
|
||||
std::string result(ctime(&time));
|
||||
|
||||
if (!result.empty())
|
||||
{
|
||||
result = result.substr(11, 8);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ChatLogManager
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManager::install()
|
||||
{
|
||||
LOG("ChatLogManager", ("chatLogMinutes(%d)", ConfigServerUtility::getChatLogMinutes()));
|
||||
LOG("ChatLogManager", ("serverMaxChatLogLines(%d)", ConfigServerUtility::getServerMaxChatLogLines()));
|
||||
LOG("ChatLogManager", ("playerMaxChatLogLines(%d)", ConfigServerUtility::getPlayerMaxChatLogLines()));
|
||||
LOG("ChatLogManager", ("chatLogManagerLoggingEnabled(%s)", ConfigServerUtility::isChatLogManagerLoggingEnabled() ? "yes" : "no"));
|
||||
|
||||
ExitChain::add(&remove, "ChatLogManager::remove");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManager::remove()
|
||||
{
|
||||
while (!s_chatMessageList.empty())
|
||||
{
|
||||
MessageList::iterator iterMessageList = s_chatMessageList.begin();
|
||||
|
||||
delete iterMessageList->first;
|
||||
|
||||
s_chatMessageList.erase(iterMessageList);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManager::logChat(Unicode::String const & fromPlayer, Unicode::String const & toPlayer, Unicode::String const & message, Unicode::String const & channel, int const messageIndex, time_t const time)
|
||||
{
|
||||
addChatLogEntry(fromPlayer, toPlayer, message, channel, messageIndex, time);
|
||||
purgeChatLog();
|
||||
|
||||
if (ConfigServerUtility::isChatLogManagerLoggingEnabled())
|
||||
{
|
||||
printPlayerLog();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int ChatLogManager::getNextMessageIndex()
|
||||
{
|
||||
return s_currentIndex++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ChatLogManager::getChatMessage(int const messageIndex, Unicode::String &chatMessage)
|
||||
{
|
||||
bool result = false;
|
||||
ChatLog::const_iterator iterChatLog = s_chatLog.find(messageIndex);
|
||||
|
||||
if (iterChatLog != s_chatLog.end())
|
||||
{
|
||||
result = true;
|
||||
chatMessage.clear();
|
||||
ChatLogEntry const &chatLogEntry = iterChatLog->second;
|
||||
|
||||
buildLogEntry(chatMessage, chatLogEntry.getFromPlayer(), chatLogEntry.getToPlayer(), chatLogEntry.getText(), chatLogEntry.getChannel(), chatLogEntry.getTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGC(ConfigServerUtility::isChatLogManagerLoggingEnabled(), "ChatLogManager", ("Unable to find chat log message(%d)\n", messageIndex));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ChatLogManager::getChatMessage(int const messageIndex, Unicode::String &fromPlayer, Unicode::String &toPlayer, Unicode::String &text, Unicode::String &channel, time_t &time)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
ChatLog::const_iterator iterChatLog = s_chatLog.find(messageIndex);
|
||||
|
||||
if (iterChatLog != s_chatLog.end())
|
||||
{
|
||||
result = true;
|
||||
ChatLogEntry const &chatLogEntry = iterChatLog->second;
|
||||
|
||||
fromPlayer = chatLogEntry.getFromPlayer();
|
||||
toPlayer = chatLogEntry.getToPlayer();
|
||||
text = chatLogEntry.getText();
|
||||
channel = chatLogEntry.getChannel();
|
||||
time = chatLogEntry.getTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WARNING(true, ("Unable to find chat log message(%d)\n", messageIndex));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManager::buildLogEntry(Unicode::String &result, Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, time_t const time)
|
||||
{
|
||||
result.clear();
|
||||
result.append(Unicode::narrowToWide(getTimeStringShort(time)));
|
||||
result.append(Unicode::narrowToWide(" ["));
|
||||
result.append(channel);
|
||||
result.append(Unicode::narrowToWide("] "));
|
||||
result.append(fromPlayer);
|
||||
|
||||
if (!toPlayer.empty())
|
||||
{
|
||||
result.append(Unicode::narrowToWide(" -> "));
|
||||
result.append(toPlayer);
|
||||
}
|
||||
|
||||
result.append(Unicode::narrowToWide(": "));
|
||||
result.append(message);
|
||||
result.append(Unicode::narrowToWide("\n"));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ChatLogManager::isPlayerInLogs(Unicode::String const &player)
|
||||
{
|
||||
return (s_playerLog.find(Unicode::toLower(player)) != s_playerLog.end());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChatLogManager::getReportHeader(Unicode::String & header, std::string const &reportingPlayer, NetworkId const &reportingPlayerNetworkId, std::string const &reportingPlayerStationName, uint32 reportingPlayerStationId, std::string const &harassingPlayer, NetworkId const &harassingPlayerNetworkId, std::string const &harassingPlayerStationName, uint32 harassingPlayerStationId)
|
||||
{
|
||||
header.clear();
|
||||
header.append(Unicode::narrowToWide("\n\n//--------------------------------------------------------\n"));
|
||||
|
||||
FormattedString<512> fs;
|
||||
|
||||
// Reporting
|
||||
|
||||
header.append(Unicode::narrowToWide(fs.sprintf("Reporting: %s (%s)", reportingPlayer.c_str(), reportingPlayerNetworkId.getValueString().c_str())));
|
||||
|
||||
if (!reportingPlayerStationName.empty() || (reportingPlayerStationId > 0))
|
||||
{
|
||||
header.append(Unicode::narrowToWide(" Station ID:"));
|
||||
if (!reportingPlayerStationName.empty())
|
||||
header.append(Unicode::narrowToWide(fs.sprintf(" %s", reportingPlayerStationName.c_str())));
|
||||
if (reportingPlayerStationId > 0)
|
||||
header.append(Unicode::narrowToWide(fs.sprintf(" (%lu)", reportingPlayerStationId)));
|
||||
}
|
||||
|
||||
header.append(Unicode::narrowToWide("\n"));
|
||||
|
||||
// Harassing
|
||||
|
||||
header.append(Unicode::narrowToWide(fs.sprintf("Harassing: %s (%s)", harassingPlayer.c_str(), harassingPlayerNetworkId.getValueString().c_str())));
|
||||
|
||||
if (!harassingPlayerStationName.empty() || (harassingPlayerStationId > 0))
|
||||
{
|
||||
header.append(Unicode::narrowToWide(" Station ID:"));
|
||||
if (!harassingPlayerStationName.empty())
|
||||
header.append(Unicode::narrowToWide(fs.sprintf(" %s", harassingPlayerStationName.c_str())));
|
||||
if (harassingPlayerStationId > 0)
|
||||
header.append(Unicode::narrowToWide(fs.sprintf(" (%lu)", harassingPlayerStationId)));
|
||||
}
|
||||
|
||||
header.append(Unicode::narrowToWide("\n"));
|
||||
|
||||
// Creation time
|
||||
|
||||
header.append(Unicode::narrowToWide(fs.sprintf("Log Creation Time: %s\n", getTimeString(Os::getRealSystemTime()).c_str())));
|
||||
|
||||
// Time length
|
||||
|
||||
header.append(Unicode::narrowToWide(fs.sprintf("Log Time Length: %d minutes\n", ConfigServerUtility::getChatLogMinutes())));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -0,0 +1,41 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// ChatLogManager.h
|
||||
// Copyright Sony Online Entertainment, Inc.
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef INCLUDED_ChatLogManager_H
|
||||
#define INCLUDED_ChatLogManager_H
|
||||
|
||||
class NetworkId;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class ChatLogManager
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
static void logChat(Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, int const messageIndex, time_t const time);
|
||||
static bool getChatMessage(int const messageIndex, Unicode::String &fromPlayer, Unicode::String &toPlayer, Unicode::String &text, Unicode::String &channel, time_t &time);
|
||||
static bool getChatMessage(int const messageIndex, Unicode::String &chatMessage);
|
||||
static int getNextMessageIndex();
|
||||
static void buildLogEntry(Unicode::String &result, Unicode::String const &fromPlayer, Unicode::String const &toPlayer, Unicode::String const &message, Unicode::String const &channel, time_t const time);
|
||||
static bool isPlayerInLogs(Unicode::String const &player);
|
||||
static void getReportHeader(Unicode::String & header, std::string const &reportingPlayer, NetworkId const &reportingPlayerNetworkId, std::string const &reportingPlayerStationName, uint32 reportingPlayerStationId, std::string const &harassingPlayer, NetworkId const &harassingPlayerNetworkId, std::string const &harassingPlayerStationName, uint32 harassingPlayerStationId);
|
||||
|
||||
private:
|
||||
|
||||
// Disable
|
||||
|
||||
ChatLogManager();
|
||||
~ChatLogManager();
|
||||
ChatLogManager(ChatLogManager const &);
|
||||
ChatLogManager &operator =(ChatLogManager const &);
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
||||
#endif // INCLUDED_ChatLogManager_H
|
||||
@@ -0,0 +1,316 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ClusterWideDataManager.cpp
|
||||
// Copyright 2004 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/ClusterWideDataManager.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
unsigned long ClusterWideDataManager::ms_lockKeyCounter = 0;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
ClusterWideDataManager::ClusterWideDataManager(std::string const & managerName) :
|
||||
m_managerName(managerName),
|
||||
m_dictionaryMap()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ClusterWideDataManager::~ClusterWideDataManager()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ClusterWideDataManager::getElement(std::string const & elementNameRegex,
|
||||
bool const lockElements,
|
||||
std::vector<std::string> & elementNameList,
|
||||
std::vector<ValueDictionary> & elementDictionaryList,
|
||||
unsigned long & lockKey)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
// allocate a new lock key; if we end up not actually
|
||||
// using the new lock key, we will "put it back"
|
||||
if (lockElements)
|
||||
{
|
||||
++ms_lockKeyCounter;
|
||||
|
||||
// handle wraparound
|
||||
if (ms_lockKeyCounter == 0)
|
||||
ms_lockKeyCounter = 1;
|
||||
}
|
||||
|
||||
elementNameList.clear();
|
||||
elementDictionaryList.clear();
|
||||
lockKey = 0;
|
||||
|
||||
bool useRegexCompare = isElementNameRegex(elementNameRegex);
|
||||
std::vector<ElementData *> tempElementDictionaryList;
|
||||
|
||||
for (ElementDataMap::iterator iter = m_dictionaryMap.begin(); iter != m_dictionaryMap.end(); ++iter)
|
||||
{
|
||||
if (isMatchElementName(elementNameRegex, iter->first, useRegexCompare))
|
||||
{
|
||||
// if element is locked and request wanted to lock
|
||||
// returned elements, don't need to look any further
|
||||
if ((lockElements) && ((iter->second).lockKey > 0))
|
||||
{
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// found a match, add the element name to return list
|
||||
elementNameList.push_back(iter->first);
|
||||
|
||||
// if request wanted to lock returned elements, don't
|
||||
// put the dictionary on the return list yet, because
|
||||
// if it's a regular expression search, the request
|
||||
// may still fail if a matching element after this
|
||||
// is locked, and we will have wasted time putting
|
||||
// the dictionary on the returned list, which makes
|
||||
// a copy of the dictionary, which could be expensive;
|
||||
// so we will put a reference to the dictionary into
|
||||
// a temporary list, and at the end, copy them over
|
||||
// into the return dictionary list
|
||||
if (lockElements)
|
||||
tempElementDictionaryList.push_back(&(iter->second));
|
||||
else
|
||||
elementDictionaryList.push_back((iter->second).dictionary);
|
||||
|
||||
// if not using regular expression, we already found
|
||||
// the one match, so don't need to look any further
|
||||
if (!useRegexCompare)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if successful, copy matching dictionary from temp list to return list
|
||||
if ((success) && (lockElements))
|
||||
{
|
||||
for (std::vector<ElementData *>::iterator iter2 = tempElementDictionaryList.begin(); iter2 != tempElementDictionaryList.end(); ++iter2)
|
||||
{
|
||||
// lock the elements in the return list
|
||||
(*iter2)->lockKey = ms_lockKeyCounter;
|
||||
|
||||
elementDictionaryList.push_back((*iter2)->dictionary);
|
||||
}
|
||||
|
||||
// return the lock key to the caller that can be used
|
||||
// later to unlock the elements in the return list
|
||||
if (!elementDictionaryList.empty())
|
||||
lockKey = ms_lockKeyCounter;
|
||||
}
|
||||
|
||||
// if new lock key was not used, "put it back"
|
||||
if (lockElements)
|
||||
{
|
||||
if ((!success) || (elementDictionaryList.empty()))
|
||||
--ms_lockKeyCounter;
|
||||
}
|
||||
|
||||
// if failure, make sure all return lists are empty
|
||||
if (!success)
|
||||
{
|
||||
elementNameList.clear();
|
||||
elementDictionaryList.clear();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ClusterWideDataManager::releaseLock(unsigned long const lockKey)
|
||||
{
|
||||
// if no lock specified, no elements will be unlocked
|
||||
if (lockKey == 0)
|
||||
return 0;
|
||||
|
||||
int numberElementsUnlocked = 0;
|
||||
|
||||
for (ElementDataMap::iterator iter = m_dictionaryMap.begin(); iter != m_dictionaryMap.end(); ++iter)
|
||||
{
|
||||
if (((iter->second).lockKey > 0) && ((iter->second).lockKey == lockKey))
|
||||
{
|
||||
(iter->second).lockKey = 0;
|
||||
++numberElementsUnlocked;
|
||||
}
|
||||
}
|
||||
|
||||
return numberElementsUnlocked;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ClusterWideDataManager::removeElement(std::string const & elementNameRegex, unsigned long const lockKey)
|
||||
{
|
||||
// if no lock specified, no elements will be removed
|
||||
if (lockKey == 0)
|
||||
return 0;
|
||||
|
||||
int numberElementsRemoved = 0;
|
||||
bool useRegexCompare = isElementNameRegex(elementNameRegex);
|
||||
|
||||
for (ElementDataMap::iterator iter = m_dictionaryMap.begin(); iter != m_dictionaryMap.end();)
|
||||
{
|
||||
if (isMatchElementName(elementNameRegex, iter->first, useRegexCompare))
|
||||
{
|
||||
if (((iter->second).lockKey > 0) && ((iter->second).lockKey == lockKey))
|
||||
{
|
||||
m_dictionaryMap.erase(iter++);
|
||||
++numberElementsRemoved;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
|
||||
// if not using regular expression, we already found
|
||||
// the one match, so don't need to look any further
|
||||
if (!useRegexCompare)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
return numberElementsRemoved;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ClusterWideDataManager::removeElementByOwnerId(unsigned long const ownerId)
|
||||
{
|
||||
// if no ownerId specified, no elements will be removed
|
||||
if (ownerId == 0)
|
||||
return 0;
|
||||
|
||||
// remove elements regardless of whether they are locked or not
|
||||
int numberElementsRemoved = 0;
|
||||
|
||||
for (ElementDataMap::iterator iter = m_dictionaryMap.begin(); iter != m_dictionaryMap.end();)
|
||||
{
|
||||
if ((iter->second).ownerId == ownerId)
|
||||
{
|
||||
m_dictionaryMap.erase(iter++);
|
||||
++numberElementsRemoved;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
return numberElementsRemoved;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ClusterWideDataManager::updateDictionary(std::string const & elementNameRegex, ValueDictionary const & dictionary, unsigned long const lockKey)
|
||||
{
|
||||
return updateDictionaryHelper(elementNameRegex, dictionary, false, 0, lockKey);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ClusterWideDataManager::replaceDictionary(std::string const & elementNameRegex, ValueDictionary const & dictionary, unsigned long const ownerId, unsigned long const lockKey)
|
||||
{
|
||||
return updateDictionaryHelper(elementNameRegex, dictionary, true, ownerId, lockKey);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ClusterWideDataManager::updateDictionaryHelper(std::string const & elementNameRegex, ValueDictionary const & dictionary, bool const overwriteDictionary, unsigned long const ownerId, unsigned long const lockKey)
|
||||
{
|
||||
int numberElementsUpdated = 0;
|
||||
bool foundMatch = false;
|
||||
bool useRegexCompare = isElementNameRegex(elementNameRegex);
|
||||
|
||||
for (ElementDataMap::iterator iter = m_dictionaryMap.begin(); iter != m_dictionaryMap.end(); ++iter)
|
||||
{
|
||||
if (isMatchElementName(elementNameRegex, iter->first, useRegexCompare))
|
||||
{
|
||||
foundMatch = true;
|
||||
|
||||
if (((iter->second).lockKey > 0) && ((iter->second).lockKey == lockKey))
|
||||
{
|
||||
if (overwriteDictionary)
|
||||
{
|
||||
(iter->second).ownerId = ownerId;
|
||||
(iter->second).dictionary = dictionary;
|
||||
}
|
||||
else
|
||||
{
|
||||
(iter->second).dictionary.insert(dictionary);
|
||||
}
|
||||
|
||||
++numberElementsUpdated;
|
||||
}
|
||||
|
||||
// if not using regular expression, we already found
|
||||
// the one match, so don't need to look any further
|
||||
if (!useRegexCompare)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if no match was found, and a single element was specified,
|
||||
// and overwrite was specified, insert it
|
||||
if ((!useRegexCompare) && (!foundMatch) && (overwriteDictionary))
|
||||
{
|
||||
ElementData element;
|
||||
element.lockKey = 0;
|
||||
element.ownerId = ownerId;
|
||||
element.dictionary = dictionary;
|
||||
|
||||
m_dictionaryMap[elementNameRegex] = element;
|
||||
|
||||
++numberElementsUpdated;
|
||||
}
|
||||
|
||||
return numberElementsUpdated;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ClusterWideDataManager::isElementNameRegex(std::string const & elementNameRegex)
|
||||
{
|
||||
// check for regular expression; currently we
|
||||
// only support a single * at the end of the string
|
||||
return ((elementNameRegex.length() > 0) && (elementNameRegex.rfind('*') == (elementNameRegex.length() - 1)));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ClusterWideDataManager::isMatchElementName(std::string const & elementNameRegex, std::string const & elementName, bool const useRegexCompare)
|
||||
{
|
||||
if (useRegexCompare)
|
||||
{
|
||||
if (elementNameRegex.length() == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// currently, the only regular expression we support
|
||||
// is a single * at the end of the string
|
||||
return (strncmp(elementNameRegex.c_str(), elementName.c_str(), elementNameRegex.length() - 1) == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (elementNameRegex == elementName);
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,80 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ClusterWideDataManager.h
|
||||
// Copyright 2004 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ClusterWideDataManager_H
|
||||
#define INCLUDED_ClusterWideDataManager_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedUtility/ValueDictionary.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ClusterWideDataManager
|
||||
{
|
||||
public: //ctor/dtor
|
||||
ClusterWideDataManager(std::string const & managerName);
|
||||
~ClusterWideDataManager();
|
||||
|
||||
public: // methods
|
||||
std::string const & getManagerName() const;
|
||||
bool getElement(std::string const & elementNameRegex,
|
||||
bool lockElements,
|
||||
std::vector<std::string> & elementNameList,
|
||||
std::vector<ValueDictionary> & elementDictionaryList,
|
||||
unsigned long & lockKey);
|
||||
int releaseLock(unsigned long lockKey);
|
||||
int removeElement(std::string const & elementNameRegex, unsigned long lockKey);
|
||||
int removeElementByOwnerId(unsigned long ownerId);
|
||||
int updateDictionary(std::string const & elementNameRegex, ValueDictionary const & dictionary, unsigned long lockKey);
|
||||
int replaceDictionary(std::string const & elementNameRegex, ValueDictionary const & dictionary, unsigned long ownerId, unsigned long lockKey);
|
||||
|
||||
private: // helper function
|
||||
int updateDictionaryHelper(std::string const & elementNameRegex, ValueDictionary const & dictionary, bool overwriteDictionary, unsigned long ownerId, unsigned long lockKey);
|
||||
static bool isElementNameRegex(std::string const & elementNameRegex);
|
||||
static bool isMatchElementName(std::string const & elementNameRegex, std::string const & elementName, bool useRegexCompare);
|
||||
|
||||
private: // data structures
|
||||
struct ElementData
|
||||
{
|
||||
ElementData() : lockKey(0), ownerId(0) {};
|
||||
|
||||
unsigned long lockKey;
|
||||
unsigned long ownerId;
|
||||
ValueDictionary dictionary;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, ElementData> ElementDataMap;
|
||||
|
||||
private:
|
||||
std::string const m_managerName;
|
||||
ElementDataMap m_dictionaryMap;
|
||||
|
||||
// for assigning lock keys
|
||||
static unsigned long ms_lockKeyCounter;
|
||||
|
||||
// Disabled.
|
||||
ClusterWideDataManager();
|
||||
ClusterWideDataManager(ClusterWideDataManager const &);
|
||||
ClusterWideDataManager &operator =(ClusterWideDataManager const &);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline std::string const & ClusterWideDataManager::getManagerName() const
|
||||
{
|
||||
return m_managerName;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,574 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ClusterWideDataManagerList.cpp
|
||||
// Copyright 2004 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/ClusterWideDataManagerList.h"
|
||||
|
||||
#include "serverUtility/ClusterWideDataManager.h"
|
||||
#include "serverUtility/ServerConnection.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include "sharedMessageDispatch/Receiver.h"
|
||||
#include "sharedNetworkMessages/ClusterWideDataGetElementMessage.h"
|
||||
#include "sharedNetworkMessages/ClusterWideDataGetElementResponseMessage.h"
|
||||
#include "sharedNetworkMessages/ClusterWideDataReleaseLockMessage.h"
|
||||
#include "sharedNetworkMessages/ClusterWideDataRemoveElementMessage.h"
|
||||
#include "sharedNetworkMessages/ClusterWideDataUpdateDictionaryMessage.h"
|
||||
#include "sharedUtility/ValueDictionaryArchive.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace ClusterWideDataManagerListNamespace
|
||||
{
|
||||
struct LockInfo
|
||||
{
|
||||
LockInfo() : lockKey(0), lockTime(0.0), managerName() {};
|
||||
|
||||
unsigned long lockKey;
|
||||
float lockTime;
|
||||
std::string managerName;
|
||||
};
|
||||
|
||||
struct QueuedRequestInfo
|
||||
{
|
||||
QueuedRequestInfo() : processId(0), requestTime(0.0), request(NULL), server(NULL) {};
|
||||
|
||||
unsigned long processId;
|
||||
float requestTime;
|
||||
ClusterWideDataGetElementMessage * request;
|
||||
ServerConnection * server;
|
||||
};
|
||||
|
||||
typedef std::map<unsigned long, QueuedRequestInfo> QueuedRequestList;
|
||||
|
||||
typedef std::multimap<unsigned long, LockInfo> ServerLockList;
|
||||
typedef std::pair<ServerLockList::const_iterator, ServerLockList::const_iterator> ServerLockListConstRange;
|
||||
typedef std::pair<ServerLockList::iterator, ServerLockList::iterator> ServerLockListRange;
|
||||
|
||||
typedef std::map<std::string, ClusterWideDataManager *> ManagerList;
|
||||
|
||||
typedef std::map<unsigned long, float> LockTimeList;
|
||||
|
||||
// tracks requests which are queued because elements are locked
|
||||
unsigned long s_queuedRequestNumber = 0;
|
||||
QueuedRequestList s_queuedRequestList;
|
||||
|
||||
// tracks servers and the locks they own
|
||||
ServerLockList s_serverLockList;
|
||||
|
||||
// tracks the different Cluster wide data managers
|
||||
ManagerList s_managerList;
|
||||
|
||||
// tracks when locks are assigned so they can be automatically released
|
||||
// after a certain amount of time and the owner hasn't release them yet
|
||||
float s_oldestLockAge = 0.0;
|
||||
int s_lockTimeoutValue = 0;
|
||||
LockTimeList s_lockTimeList;
|
||||
|
||||
// accumulate game time to be used in detecting expired locks
|
||||
float s_totalGameTime = 0.0;
|
||||
|
||||
ClusterWideDataManager * getClusterWideDataManager(std::string const & managerName, bool const createIfNotExist);
|
||||
void processQueuedRequests();
|
||||
bool handleClusterWideDataGetElementMessage(ClusterWideDataGetElementMessage const & msg, ServerConnection & server);
|
||||
void handleClusterWideDataReleaseLockMessage(ClusterWideDataReleaseLockMessage const & msg, ServerConnection const & server);
|
||||
void handleClusterWideDataRemoveElementMessage(ClusterWideDataRemoveElementMessage const & msg, ServerConnection const & server);
|
||||
void handleClusterWideDataUpdateDictionaryMessage(ClusterWideDataUpdateDictionaryMessage const & msg, ServerConnection const & server);
|
||||
void removeFromLockTimeList(unsigned long const lockKey);
|
||||
void removeExpiredLocks();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerList::install()
|
||||
{
|
||||
ExitChain::add(remove, "ClusterWideDataManagerList");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerList::remove()
|
||||
{
|
||||
// clear up queued requests
|
||||
for (ClusterWideDataManagerListNamespace::QueuedRequestList::iterator iter = ClusterWideDataManagerListNamespace::s_queuedRequestList.begin(); iter != ClusterWideDataManagerListNamespace::s_queuedRequestList.end(); ++iter)
|
||||
delete iter->second.request;
|
||||
|
||||
ClusterWideDataManagerListNamespace::s_queuedRequestList.clear();
|
||||
|
||||
// clear up cluster wide data managers
|
||||
for (ClusterWideDataManagerListNamespace::ManagerList::iterator iter2 = ClusterWideDataManagerListNamespace::s_managerList.begin(); iter2 != ClusterWideDataManagerListNamespace::s_managerList.end(); ++iter2)
|
||||
delete iter2->second;
|
||||
|
||||
ClusterWideDataManagerListNamespace::s_managerList.clear();
|
||||
|
||||
// clear up lock lists
|
||||
ClusterWideDataManagerListNamespace::s_serverLockList.clear();
|
||||
ClusterWideDataManagerListNamespace::s_lockTimeList.clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerList::update(float time)
|
||||
{
|
||||
// accumulate game time
|
||||
ClusterWideDataManagerListNamespace::s_totalGameTime += time;
|
||||
|
||||
// handle and locks that have expired
|
||||
ClusterWideDataManagerListNamespace::removeExpiredLocks();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerList::registerMessage(MessageDispatch::Receiver & messageReceiver)
|
||||
{
|
||||
messageReceiver.connectToMessage(ClusterWideDataGetElementMessage::ms_messageName.c_str());
|
||||
messageReceiver.connectToMessage(ClusterWideDataReleaseLockMessage::ms_messageName.c_str());
|
||||
messageReceiver.connectToMessage(ClusterWideDataRemoveElementMessage::ms_messageName.c_str());
|
||||
messageReceiver.connectToMessage(ClusterWideDataUpdateDictionaryMessage::ms_messageName.c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ClusterWideDataManagerList::handleMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message)
|
||||
{
|
||||
bool handledMessage = false;
|
||||
|
||||
if (message.isType(ClusterWideDataGetElementMessage::ms_messageName.c_str()))
|
||||
{
|
||||
handledMessage = true;
|
||||
|
||||
Archive::ReadIterator ri = safe_cast<const GameNetworkMessage *>(&message)->getByteStream().begin();
|
||||
|
||||
// dynamic allocation because if the request needs to be queued,
|
||||
// we will store the message off for later processing
|
||||
ClusterWideDataGetElementMessage * msg = new ClusterWideDataGetElementMessage(ri);
|
||||
|
||||
// need to cast away const here because we need to send response
|
||||
// back to source and ServerConnection::send() is non-const
|
||||
ServerConnection * server = const_cast<ServerConnection *>(dynamic_cast<ServerConnection const *>(&source));
|
||||
if (server)
|
||||
{
|
||||
if (ClusterWideDataManagerListNamespace::handleClusterWideDataGetElementMessage(*msg, *server))
|
||||
{
|
||||
delete msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
// some elements were locked, queue the request for later processing
|
||||
LOG("ClusterWideDataManagerList", ("Queuing request from server (%lu), manager name (%s), element name regex (%s), lock elements (%s), request Id (%lu)", server->getProcessId(), msg->getManagerName().c_str(), msg->getElementNameRegex().c_str(), (msg->getLockElements() ? "true" : "false"), msg->getRequestId()));
|
||||
|
||||
ClusterWideDataManagerListNamespace::QueuedRequestInfo info;
|
||||
info.processId = server->getProcessId();
|
||||
info.requestTime = ClusterWideDataManagerListNamespace::s_totalGameTime;
|
||||
info.request = msg;
|
||||
info.server = server;
|
||||
|
||||
ClusterWideDataManagerListNamespace::s_queuedRequestList[++ClusterWideDataManagerListNamespace::s_queuedRequestNumber] = info;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING(true, ("Received ClusterWideDataGetElementMessage but not from a game server - manager name (%s), element name regex (%s), lock elements (%s), request Id (%lu)", msg->getManagerName().c_str(), msg->getElementNameRegex().c_str(), (msg->getLockElements() ? "true" : "false"), msg->getRequestId()));
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
else if (message.isType(ClusterWideDataReleaseLockMessage::ms_messageName.c_str()))
|
||||
{
|
||||
handledMessage = true;
|
||||
|
||||
Archive::ReadIterator ri = safe_cast<const GameNetworkMessage *>(&message)->getByteStream().begin();
|
||||
ClusterWideDataReleaseLockMessage msg(ri);
|
||||
|
||||
ServerConnection const * server = dynamic_cast<ServerConnection const *>(&source);
|
||||
if (server)
|
||||
{
|
||||
ClusterWideDataManagerListNamespace::handleClusterWideDataReleaseLockMessage(msg, *server);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING(true, ("Received ClusterWideDataReleaseLockMessage but not from a game server - manager name (%s), lock key (%lu)", msg.getManagerName().c_str(), msg.getLockKey()));
|
||||
}
|
||||
}
|
||||
else if (message.isType(ClusterWideDataRemoveElementMessage::ms_messageName.c_str()))
|
||||
{
|
||||
handledMessage = true;
|
||||
|
||||
Archive::ReadIterator ri = safe_cast<const GameNetworkMessage *>(&message)->getByteStream().begin();
|
||||
ClusterWideDataRemoveElementMessage msg(ri);
|
||||
|
||||
ServerConnection const * server = dynamic_cast<ServerConnection const *>(&source);
|
||||
if (server)
|
||||
{
|
||||
ClusterWideDataManagerListNamespace::handleClusterWideDataRemoveElementMessage(msg, *server);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING(true, ("Received ClusterWideDataRemoveElementMessage but not from a game server - manager name (%s), element name regex (%s)", msg.getManagerName().c_str(), msg.getElementNameRegex().c_str()));
|
||||
}
|
||||
}
|
||||
else if (message.isType(ClusterWideDataUpdateDictionaryMessage::ms_messageName.c_str()))
|
||||
{
|
||||
handledMessage = true;
|
||||
|
||||
Archive::ReadIterator ri = safe_cast<const GameNetworkMessage *>(&message)->getByteStream().begin();
|
||||
ClusterWideDataUpdateDictionaryMessage msg(ri);
|
||||
|
||||
ServerConnection const * server = dynamic_cast<ServerConnection const *>(&source);
|
||||
if (server)
|
||||
{
|
||||
ClusterWideDataManagerListNamespace::handleClusterWideDataUpdateDictionaryMessage(msg, *server);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING(true, ("Received ClusterWideDataUpdateDictionaryMessage but not from a game server - manager name (%s), element name regex (%s), replace dictionary (%s)", msg.getManagerName().c_str(), msg.getElementNameRegex().c_str(), (msg.getReplaceDictionary() ? "yes" : "no")));
|
||||
}
|
||||
}
|
||||
|
||||
return handledMessage;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerList::onGameServerDisconnect(unsigned long const processId)
|
||||
{
|
||||
// remove any queued messages for the disconnected server
|
||||
int requestsDeleted = 0;
|
||||
|
||||
for (ClusterWideDataManagerListNamespace::QueuedRequestList::iterator iter = ClusterWideDataManagerListNamespace::s_queuedRequestList.begin(); iter != ClusterWideDataManagerListNamespace::s_queuedRequestList.end();)
|
||||
{
|
||||
if (iter->second.processId == processId)
|
||||
{
|
||||
delete iter->second.request;
|
||||
ClusterWideDataManagerListNamespace::s_queuedRequestList.erase(iter++);
|
||||
++requestsDeleted;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
if (requestsDeleted > 0)
|
||||
LOG("ClusterWideDataManagerList", ("Removed (%d) pending requests for disconnected server (%lu)", requestsDeleted, processId));
|
||||
|
||||
// remove any "auto remove" elements owned by the server
|
||||
int elementsRemoved = 0;
|
||||
|
||||
for (ClusterWideDataManagerListNamespace::ManagerList::const_iterator iter3 = ClusterWideDataManagerListNamespace::s_managerList.begin(); iter3 != ClusterWideDataManagerListNamespace::s_managerList.end(); ++iter3)
|
||||
{
|
||||
elementsRemoved += iter3->second->removeElementByOwnerId(processId);
|
||||
}
|
||||
|
||||
if (elementsRemoved > 0)
|
||||
LOG("ClusterWideDataManagerList", ("Removed (%d) elements for disconnected server (%lu)", elementsRemoved, processId));
|
||||
|
||||
// if server has any outstanding locks, unlock those elements
|
||||
int elementsUnlocked = 0;
|
||||
|
||||
ClusterWideDataManagerListNamespace::ServerLockListConstRange range = ClusterWideDataManagerListNamespace::s_serverLockList.equal_range(processId);
|
||||
|
||||
ClusterWideDataManager * manager = NULL;
|
||||
for (ClusterWideDataManagerListNamespace::ServerLockList::const_iterator iter2 = range.first; iter2 != range.second; ++iter2)
|
||||
{
|
||||
manager = ClusterWideDataManagerListNamespace::getClusterWideDataManager((iter2->second).managerName, false);
|
||||
if (manager)
|
||||
elementsUnlocked += manager->releaseLock((iter2->second).lockKey);
|
||||
else
|
||||
WARNING(true, ("ClusterWideDataManager (%s) not found for lock (%lu) owned by disconnected server (%lu)", (iter2->second).managerName.c_str(), (iter2->second).lockKey, processId));
|
||||
|
||||
ClusterWideDataManagerListNamespace::removeFromLockTimeList((iter2->second).lockKey);
|
||||
}
|
||||
|
||||
unsigned int locksDeleted = ClusterWideDataManagerListNamespace::s_serverLockList.erase(processId);
|
||||
|
||||
if (locksDeleted > 0)
|
||||
LOG("ClusterWideDataManagerList", ("Removed (%d) locks and unlocked (%d) elements for disconnected server (%lu)", locksDeleted, elementsUnlocked, processId));
|
||||
|
||||
// if any locks were released or any elements were removed,
|
||||
// then some elements may now be unlocked, so go through
|
||||
// the queued requests and process them
|
||||
if ((elementsUnlocked > 0) || (elementsRemoved > 0))
|
||||
ClusterWideDataManagerListNamespace::processQueuedRequests();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerList::setLockTimeoutValue(int const timeout)
|
||||
{
|
||||
LOG("ClusterWideDataManagerList", ("Setting lock timeout value to (%d) seconds", timeout));
|
||||
|
||||
ClusterWideDataManagerListNamespace::s_lockTimeoutValue = timeout;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ClusterWideDataManagerList::getNumberOfQueuedRequests()
|
||||
{
|
||||
return ClusterWideDataManagerListNamespace::s_queuedRequestList.size();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ClusterWideDataManager * ClusterWideDataManagerListNamespace::getClusterWideDataManager(std::string const & managerName, bool const createIfNotExist)
|
||||
{
|
||||
ManagerList::iterator iter = s_managerList.find(managerName);
|
||||
if (iter != s_managerList.end())
|
||||
return iter->second;
|
||||
|
||||
if (createIfNotExist)
|
||||
{
|
||||
ClusterWideDataManager * manager = new ClusterWideDataManager(managerName);
|
||||
s_managerList[managerName] = manager;
|
||||
return manager;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerListNamespace::processQueuedRequests()
|
||||
{
|
||||
for (QueuedRequestList::iterator iter = s_queuedRequestList.begin(); iter != s_queuedRequestList.end();)
|
||||
{
|
||||
if (handleClusterWideDataGetElementMessage(*(iter->second.request), *(iter->second.server)))
|
||||
{
|
||||
delete iter->second.request;
|
||||
s_queuedRequestList.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ClusterWideDataManagerListNamespace::handleClusterWideDataGetElementMessage(ClusterWideDataGetElementMessage const & msg, ServerConnection & server)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
std::vector<std::string> elementNameList;
|
||||
std::vector<ValueDictionary> elementDictionaryList;
|
||||
unsigned long lockKey = 0;
|
||||
|
||||
ClusterWideDataManager * manager = getClusterWideDataManager(msg.getManagerName(), false);
|
||||
if (manager)
|
||||
{
|
||||
success = manager->getElement(msg.getElementNameRegex(), msg.getLockElements(), elementNameList, elementDictionaryList, lockKey);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
// cut down on the log spam; don't log "browse" requests
|
||||
if (lockKey > 0)
|
||||
LOG("ClusterWideDataManagerList", ("Returned (%d) elements to server (%lu), manager name (%s), element name regex (%s), lock elements (%s), request Id (%lu), lock key (%lu)", elementNameList.size(), server.getProcessId(), msg.getManagerName().c_str(), msg.getElementNameRegex().c_str(), (msg.getLockElements() ? "true" : "false"), msg.getRequestId(), lockKey));
|
||||
|
||||
// send response
|
||||
ClusterWideDataGetElementResponseMessage resp(msg.getManagerName(), msg.getElementNameRegex(), elementNameList, elementDictionaryList, msg.getRequestId(), lockKey);
|
||||
server.send(resp, true);
|
||||
|
||||
// if a lock was acquired, add it to the lock list so if
|
||||
// the server goes down, we can unlock the locked elements
|
||||
if (lockKey > 0)
|
||||
{
|
||||
LockInfo info;
|
||||
info.lockKey = lockKey;
|
||||
info.lockTime = s_totalGameTime;
|
||||
info.managerName = msg.getManagerName();
|
||||
|
||||
IGNORE_RETURN(s_serverLockList.insert(ServerLockList::value_type(server.getProcessId(), info)));
|
||||
|
||||
s_lockTimeList[lockKey] = info.lockTime;
|
||||
|
||||
if (s_lockTimeList.size() == 1)
|
||||
s_oldestLockAge = info.lockTime;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerListNamespace::handleClusterWideDataReleaseLockMessage(ClusterWideDataReleaseLockMessage const & msg, ServerConnection const & server)
|
||||
{
|
||||
// remove the lock from the lock list
|
||||
bool foundLockToRemove = false;
|
||||
ServerLockListRange range = s_serverLockList.equal_range(server.getProcessId());
|
||||
ServerLockList::iterator iter;
|
||||
for (iter = range.first; iter != range.second; ++iter)
|
||||
{
|
||||
if ((iter->second).lockKey == msg.getLockKey())
|
||||
{
|
||||
if ((iter->second).managerName == msg.getManagerName())
|
||||
foundLockToRemove = true;
|
||||
else
|
||||
WARNING(true, ("ClusterWideDataManagerList received request to unlock lock (%lu) with incorrect manager (%s) where correct manager is (%s)", msg.getLockKey(), (msg.getManagerName()).c_str(), ((iter->second).managerName).c_str()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundLockToRemove)
|
||||
{
|
||||
// if we found a lock to remove in the ServerLockList, we remove it from the manager and the list
|
||||
ClusterWideDataManager * manager = getClusterWideDataManager(msg.getManagerName(), false);
|
||||
if (manager)
|
||||
{
|
||||
s_serverLockList.erase(iter);
|
||||
ClusterWideDataManagerListNamespace::removeFromLockTimeList(msg.getLockKey());
|
||||
|
||||
int numberElementsUnlocked = manager->releaseLock(msg.getLockKey());
|
||||
|
||||
LOG("ClusterWideDataManagerList", ("Unlocked (%d) elements for server (%lu), manager name (%s), lock key (%lu)", numberElementsUnlocked, server.getProcessId(), msg.getManagerName().c_str(), msg.getLockKey()));
|
||||
|
||||
// if any elements were unlocked, so go through the queued requests and process them
|
||||
if (numberElementsUnlocked > 0)
|
||||
processQueuedRequests();
|
||||
}
|
||||
else
|
||||
LOG("ClusterWideDataManagerList", ("ClusterWideDataManagerList received request to unlock lock but could not get a ClusterWideDataManager for manager name (%s), lock key (%lu)", msg.getManagerName().c_str(), msg.getLockKey()));
|
||||
}
|
||||
else if (iter == range.second)
|
||||
LOG("ClusterWideDataManagerList", ("ClusterWideDataManagerList received request to unlock lock but could not find any locks with matching lock key: manager name (%s), lock key (%lu)", msg.getManagerName().c_str(), msg.getLockKey()));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerListNamespace::handleClusterWideDataRemoveElementMessage(ClusterWideDataRemoveElementMessage const & msg, ServerConnection const & server)
|
||||
{
|
||||
ClusterWideDataManager * manager = getClusterWideDataManager(msg.getManagerName(), false);
|
||||
if (manager)
|
||||
{
|
||||
int numberElementsRemoved = manager->removeElement(msg.getElementNameRegex(), msg.getLockKey());
|
||||
|
||||
LOG("ClusterWideDataManagerList", ("Removed (%d) elements for server (%lu), manager name (%s), element name regex (%s), lock key (%lu)", numberElementsRemoved, server.getProcessId(), msg.getManagerName().c_str(), msg.getElementNameRegex().c_str(), msg.getLockKey()));
|
||||
|
||||
// if any elements were removed, so go through the queued requests and process them
|
||||
if (numberElementsRemoved > 0)
|
||||
processQueuedRequests();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerListNamespace::handleClusterWideDataUpdateDictionaryMessage(ClusterWideDataUpdateDictionaryMessage const & msg, ServerConnection const & server)
|
||||
{
|
||||
ClusterWideDataManager * manager = getClusterWideDataManager(msg.getManagerName(), true);
|
||||
if (manager)
|
||||
{
|
||||
if (msg.getReplaceDictionary())
|
||||
{
|
||||
int numberElementsReplaced = manager->replaceDictionary(msg.getElementNameRegex(), msg.getDictionary(), (msg.getAutoRemove() ? server.getProcessId() : 0) , msg.getLockKey());
|
||||
|
||||
LOG("ClusterWideDataManagerList", ("Replaced (%d) elements for server (%lu), manager name (%s), element name regex (%s), auto remove (%s), lock key (%lu)", numberElementsReplaced, server.getProcessId(), msg.getManagerName().c_str(), msg.getElementNameRegex().c_str(), (msg.getAutoRemove() ? "yes" : "no"), msg.getLockKey()));
|
||||
}
|
||||
else
|
||||
{
|
||||
int numberElementsUpdated = manager->updateDictionary(msg.getElementNameRegex(), msg.getDictionary(), msg.getLockKey());
|
||||
|
||||
LOG("ClusterWideDataManagerList", ("Updated (%d) elements for server (%lu), manager name (%s), element name regex (%s), lock key (%lu)", numberElementsUpdated, server.getProcessId(), msg.getManagerName().c_str(), msg.getElementNameRegex().c_str(), msg.getLockKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerListNamespace::removeFromLockTimeList(unsigned long const lockKey)
|
||||
{
|
||||
IGNORE_RETURN(s_lockTimeList.erase(lockKey));
|
||||
|
||||
if (!ClusterWideDataManagerListNamespace::s_lockTimeList.empty())
|
||||
ClusterWideDataManagerListNamespace::s_oldestLockAge = ClusterWideDataManagerListNamespace::s_lockTimeList.begin()->second;
|
||||
else
|
||||
ClusterWideDataManagerListNamespace::s_oldestLockAge = 0.0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClusterWideDataManagerListNamespace::removeExpiredLocks()
|
||||
{
|
||||
if (s_lockTimeoutValue <= 0)
|
||||
return;
|
||||
|
||||
if (s_oldestLockAge == 0.0)
|
||||
return;
|
||||
|
||||
if ((s_totalGameTime - s_oldestLockAge) < static_cast<float>(s_lockTimeoutValue))
|
||||
return;
|
||||
|
||||
if (s_lockTimeList.empty())
|
||||
{
|
||||
WARNING(true, ("ClusterWideDataManagerList mismatch - age of the oldest lock is (%.2f seconds), but there are no locks in the lock time list", (s_totalGameTime - s_oldestLockAge)));
|
||||
|
||||
s_oldestLockAge = 0.0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// get the lock key that has expired
|
||||
unsigned long oldestLockKey = 0;
|
||||
|
||||
// limit the scope of iter
|
||||
{
|
||||
LockTimeList::iterator iter = s_lockTimeList.begin();
|
||||
if (iter->second != s_oldestLockAge) //lint !e777 // we compare these two float values because we expect them to be bitwise identical
|
||||
{
|
||||
WARNING(true, ("ClusterWideDataManagerList mismatch between perceived age of the oldest lock (%.2f seconds), and the actual age of the oldest lock (%.2f seconds), lock key (%lu)", (s_totalGameTime - s_oldestLockAge), (s_totalGameTime - iter->second), iter->first));
|
||||
|
||||
s_oldestLockAge = iter->second;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// remove the lock from the lock time list
|
||||
oldestLockKey = iter->first;
|
||||
|
||||
// ***iter is invalid after this call; also the call will change s_oldestLockAge
|
||||
// to be the age of the next oldest lock, or 0 if there are no more locks***
|
||||
removeFromLockTimeList(oldestLockKey);
|
||||
}
|
||||
|
||||
// find the lock info for the expired lock key
|
||||
ServerLockList::iterator iter2 = s_serverLockList.begin();
|
||||
for (; iter2 != s_serverLockList.end(); ++iter2)
|
||||
{
|
||||
if ((iter2->second).lockKey == oldestLockKey)
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter2 == s_serverLockList.end())
|
||||
{
|
||||
WARNING(true, ("ClusterWideDataManagerList could not locate lock info for expired lock key (%lu)", oldestLockKey));
|
||||
return;
|
||||
}
|
||||
|
||||
// release the locked elements
|
||||
int numberElementsUnlocked = 0;
|
||||
ClusterWideDataManager * manager = getClusterWideDataManager((iter2->second).managerName, false);
|
||||
if (manager)
|
||||
{
|
||||
numberElementsUnlocked = manager->releaseLock((iter2->second).lockKey);
|
||||
|
||||
LOG("ClusterWideDataManagerList", ("Unlocked (%d) elements for expired lock key (%lu) owned by server (%lu)", numberElementsUnlocked, (iter2->second).lockKey, iter2->first));
|
||||
}
|
||||
else
|
||||
{
|
||||
WARNING(true, ("ClusterWideDataManager (%s) not found for expired lock key (%lu) owned by server (%lu)", (iter2->second).managerName.c_str(), (iter2->second).lockKey, iter2->first));
|
||||
}
|
||||
|
||||
// remove the lock from the lock list
|
||||
s_serverLockList.erase(iter2);
|
||||
|
||||
// if any elements were unlocked, so go through the queued requests and process them
|
||||
if (numberElementsUnlocked > 0)
|
||||
processQueuedRequests();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,40 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ClusterWideDataManagerList.h
|
||||
// Copyright 2004 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ClusterWideDataManagerList_H
|
||||
#define INCLUDED_ClusterWideDataManagerList_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace MessageDispatch
|
||||
{
|
||||
class Emitter;
|
||||
class MessageBase;
|
||||
class Receiver;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ClusterWideDataManagerList
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void remove();
|
||||
static void update(float time);
|
||||
|
||||
static void registerMessage(MessageDispatch::Receiver & messageReceiver);
|
||||
static bool handleMessage(MessageDispatch::Emitter const & source, MessageDispatch::MessageBase const & message);
|
||||
static void onGameServerDisconnect(unsigned long processId);
|
||||
static void setLockTimeoutValue(int timeout);
|
||||
static int getNumberOfQueuedRequests();
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
// ConfigServerUtility.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/ConfigServerUtility.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace ConfigServerUtilityNamespace
|
||||
{
|
||||
int spawnCookie;
|
||||
int chatLogMinutes;
|
||||
int serverMaxChatLogLines;
|
||||
int playerMaxChatLogLines;
|
||||
bool chatLogManagerLoggingEnabled;
|
||||
}
|
||||
|
||||
using namespace ConfigServerUtilityNamespace;
|
||||
|
||||
#define KEY_INT(a,b) (a = ConfigFile::getKeyInt("ServerUtility", #a, b))
|
||||
#define KEY_BOOL(a,b) (a = ConfigFile::getKeyBool("ServerUtility", #a, b))
|
||||
#define KEY_FLOAT(a,b) (a = ConfigFile::getKeyFloat("ServerUtility", #a, b))
|
||||
#define KEY_STRING(a,b) (a = ConfigFile::getKeyString("ServerUtility", #a, b))
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ConfigServerUtility::ConfigServerUtility()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ConfigServerUtility::~ConfigServerUtility()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int ConfigServerUtility::getSpawnCookie()
|
||||
{
|
||||
return spawnCookie;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int ConfigServerUtility::getChatLogMinutes()
|
||||
{
|
||||
return chatLogMinutes;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int ConfigServerUtility::getServerMaxChatLogLines()
|
||||
{
|
||||
return serverMaxChatLogLines;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int ConfigServerUtility::getPlayerMaxChatLogLines()
|
||||
{
|
||||
return playerMaxChatLogLines;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool ConfigServerUtility::isChatLogManagerLoggingEnabled()
|
||||
{
|
||||
return chatLogManagerLoggingEnabled;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ConfigServerUtility::install()
|
||||
{
|
||||
KEY_INT(spawnCookie, 0);
|
||||
KEY_INT(chatLogMinutes, 10);
|
||||
KEY_INT(serverMaxChatLogLines, 5000);
|
||||
KEY_INT(playerMaxChatLogLines, 200);
|
||||
KEY_BOOL(chatLogManagerLoggingEnabled, false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ConfigServerUtility::remove()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// ConfigServerUtility.h
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_ConfigServerUtility_H
|
||||
#define _INCLUDED_ConfigServerUtility_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class ConfigServerUtility
|
||||
{
|
||||
public:
|
||||
~ConfigServerUtility();
|
||||
|
||||
static int getSpawnCookie ();
|
||||
static int getChatLogMinutes();
|
||||
static int getServerMaxChatLogLines();
|
||||
static int getPlayerMaxChatLogLines();
|
||||
static bool isChatLogManagerLoggingEnabled();
|
||||
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
private:
|
||||
ConfigServerUtility();
|
||||
ConfigServerUtility & operator = (const ConfigServerUtility & rhs);
|
||||
ConfigServerUtility(const ConfigServerUtility & source);
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_ConfigServerUtility_H
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef INCLUDED_FirstServerUtility_H
|
||||
#define INCLUDED_FirstServerUtility_H
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedMemoryManager/FirstSharedMemoryManager.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,433 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FreeCtsDataTable.cpp
|
||||
// Copyright 2008 Sony Online Entertainment LLC (SOE)
|
||||
// All rights reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/FreeCtsDataTable.h"
|
||||
|
||||
#include "sharedFoundation/CalendarTime.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedUtility/DataTable.h"
|
||||
#include "sharedUtility/DataTableManager.h"
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace FreeCtsDataTableNamespace
|
||||
{
|
||||
std::multimap<std::string, FreeCtsDataTable::FreeCtsInfo> s_freeCtsList;
|
||||
|
||||
bool s_dataLoaded = false;
|
||||
std::string s_freeCtsFileName;
|
||||
void loadData();
|
||||
|
||||
time_t convertToEpoch(int year, int month, int day, int hour, int minute, int second);
|
||||
}
|
||||
|
||||
using namespace FreeCtsDataTableNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void FreeCtsDataTableNamespace::loadData()
|
||||
{
|
||||
if (s_dataLoaded)
|
||||
return;
|
||||
|
||||
s_dataLoaded = true;
|
||||
|
||||
// set up data to determine free CTS
|
||||
s_freeCtsFileName = ConfigFile::getKeyString("FreeCts", "freeCtsFilename", "");
|
||||
if (!s_freeCtsFileName.empty())
|
||||
{
|
||||
DataTable * table = DataTableManager::getTable(s_freeCtsFileName, true);
|
||||
if (table)
|
||||
{
|
||||
int const columnRuleName = table->findColumnNumber("ruleName");
|
||||
int const columnRuleDescription = table->findColumnNumber("ruleDescription");
|
||||
|
||||
int const columnSourceClusterList = table->findColumnNumber("sourceClusterList");
|
||||
int const columnTargetClusterList = table->findColumnNumber("targetClusterList");
|
||||
|
||||
int const columnStartDateYr = table->findColumnNumber("startDateYr");
|
||||
int const columnStartDateMo = table->findColumnNumber("startDateMo");
|
||||
int const columnStartDateDy = table->findColumnNumber("startDateDy");
|
||||
int const columnStartDateHr = table->findColumnNumber("startDateHr");
|
||||
int const columnStartDateMin = table->findColumnNumber("startDateMin");
|
||||
int const columnStartDateSec = table->findColumnNumber("startDateSec");
|
||||
|
||||
int const columnEndDateYr = table->findColumnNumber("endDateYr");
|
||||
int const columnEndDateMo = table->findColumnNumber("endDateMo");
|
||||
int const columnEndDateDy = table->findColumnNumber("endDateDy");
|
||||
int const columnEndDateHr = table->findColumnNumber("endDateHr");
|
||||
int const columnEndDateMin = table->findColumnNumber("endDateMin");
|
||||
int const columnEndDateSec = table->findColumnNumber("endDateSec");
|
||||
|
||||
int const columnCharacterCreateDateRangeLowerYr = table->findColumnNumber("characterCreateDateRangeLowerYr");
|
||||
int const columnCharacterCreateDateRangeLowerMo = table->findColumnNumber("characterCreateDateRangeLowerMo");
|
||||
int const columnCharacterCreateDateRangeLowerDy = table->findColumnNumber("characterCreateDateRangeLowerDy");
|
||||
int const columnCharacterCreateDateRangeLowerHr = table->findColumnNumber("characterCreateDateRangeLowerHr");
|
||||
int const columnCharacterCreateDateRangeLowerMin = table->findColumnNumber("characterCreateDateRangeLowerMin");
|
||||
int const columnCharacterCreateDateRangeLowerSec = table->findColumnNumber("characterCreateDateRangeLowerSec");
|
||||
|
||||
int const columnCharacterCreateDateRangeUpperYr = table->findColumnNumber("characterCreateDateRangeUpperYr");
|
||||
int const columnCharacterCreateDateRangeUpperMo = table->findColumnNumber("characterCreateDateRangeUpperMo");
|
||||
int const columnCharacterCreateDateRangeUpperDy = table->findColumnNumber("characterCreateDateRangeUpperDy");
|
||||
int const columnCharacterCreateDateRangeUpperHr = table->findColumnNumber("characterCreateDateRangeUpperHr");
|
||||
int const columnCharacterCreateDateRangeUpperMin = table->findColumnNumber("characterCreateDateRangeUpperMin");
|
||||
int const columnCharacterCreateDateRangeUpperSec = table->findColumnNumber("characterCreateDateRangeUpperSec");
|
||||
|
||||
FATAL((columnRuleName < 0), ("column \"ruleName\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnRuleDescription < 0), ("column \"ruleDescription\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
|
||||
FATAL((columnSourceClusterList < 0), ("column \"sourceClusterList\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnTargetClusterList < 0), ("column \"targetClusterList\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
|
||||
FATAL((columnStartDateYr < 0), ("column \"startDateYr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnStartDateMo < 0), ("column \"startDateMo\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnStartDateDy < 0), ("column \"startDateDy\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnStartDateHr < 0), ("column \"startDateHr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnStartDateMin < 0), ("column \"startDateMin\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnStartDateSec < 0), ("column \"startDateSec\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
|
||||
FATAL((columnEndDateYr < 0), ("column \"endDateYr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnEndDateMo < 0), ("column \"endDateMo\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnEndDateDy < 0), ("column \"endDateDy\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnEndDateHr < 0), ("column \"endDateHr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnEndDateMin < 0), ("column \"endDateMin\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnEndDateSec < 0), ("column \"endDateSec\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
|
||||
FATAL((columnCharacterCreateDateRangeLowerYr < 0), ("column \"characterCreateDateRangeLowerYr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeLowerMo < 0), ("column \"characterCreateDateRangeLowerMo\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeLowerDy < 0), ("column \"characterCreateDateRangeLowerDy\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeLowerHr < 0), ("column \"characterCreateDateRangeLowerHr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeLowerMin < 0), ("column \"characterCreateDateRangeLowerMin\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeLowerSec < 0), ("column \"characterCreateDateRangeLowerSec\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
|
||||
FATAL((columnCharacterCreateDateRangeUpperYr < 0), ("column \"characterCreateDateRangeUpperYr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeUpperMo < 0), ("column \"characterCreateDateRangeUpperMo\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeUpperDy < 0), ("column \"characterCreateDateRangeUpperDy\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeUpperHr < 0), ("column \"characterCreateDateRangeUpperHr\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeUpperMin < 0), ("column \"characterCreateDateRangeUpperMin\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
FATAL((columnCharacterCreateDateRangeUpperSec < 0), ("column \"characterCreateDateRangeUpperSec\" not found in %s", s_freeCtsFileName.c_str()));
|
||||
|
||||
std::string sourceClusterList, targetClusterList;
|
||||
int startDateYr, startDateMo, startDateDy, startDateHr, startDateMin, startDateSec;
|
||||
int endDateYr, endDateMo, endDateDy, endDateHr, endDateMin, endDateSec;
|
||||
int characterCreateDateRangeLowerYr, characterCreateDateRangeLowerMo, characterCreateDateRangeLowerDy, characterCreateDateRangeLowerHr, characterCreateDateRangeLowerMin, characterCreateDateRangeLowerSec;
|
||||
int characterCreateDateRangeUpperYr, characterCreateDateRangeUpperMo, characterCreateDateRangeUpperDy, characterCreateDateRangeUpperHr, characterCreateDateRangeUpperMin, characterCreateDateRangeUpperSec;
|
||||
|
||||
FreeCtsDataTable::FreeCtsInfo freeCtsInfo;
|
||||
|
||||
Unicode::UnicodeStringVector tokensSourceClusterList, tokensTargetClusterList;
|
||||
Unicode::UnicodeStringVector::const_iterator tokensIter;
|
||||
static Unicode::String const clusterListDelimiters(Unicode::narrowToWide(", "));
|
||||
|
||||
int const numRows = table->getNumRows();
|
||||
for (int i = 0; i < numRows; ++i)
|
||||
{
|
||||
freeCtsInfo.ruleName = table->getStringValue(columnRuleName, i);
|
||||
freeCtsInfo.ruleDescription = table->getStringValue(columnRuleDescription, i);
|
||||
|
||||
sourceClusterList = table->getStringValue(columnSourceClusterList, i);
|
||||
targetClusterList = table->getStringValue(columnTargetClusterList, i);
|
||||
|
||||
startDateYr = table->getIntValue(columnStartDateYr, i);
|
||||
startDateMo = table->getIntValue(columnStartDateMo, i);
|
||||
startDateDy = table->getIntValue(columnStartDateDy, i);
|
||||
startDateHr = table->getIntValue(columnStartDateHr, i);
|
||||
startDateMin = table->getIntValue(columnStartDateMin, i);
|
||||
startDateSec = table->getIntValue(columnStartDateSec, i);
|
||||
|
||||
endDateYr = table->getIntValue(columnEndDateYr, i);
|
||||
endDateMo = table->getIntValue(columnEndDateMo, i);
|
||||
endDateDy = table->getIntValue(columnEndDateDy, i);
|
||||
endDateHr = table->getIntValue(columnEndDateHr, i);
|
||||
endDateMin = table->getIntValue(columnEndDateMin, i);
|
||||
endDateSec = table->getIntValue(columnEndDateSec, i);
|
||||
|
||||
characterCreateDateRangeLowerYr = table->getIntValue(columnCharacterCreateDateRangeLowerYr, i);
|
||||
characterCreateDateRangeLowerMo = table->getIntValue(columnCharacterCreateDateRangeLowerMo, i);
|
||||
characterCreateDateRangeLowerDy = table->getIntValue(columnCharacterCreateDateRangeLowerDy, i);
|
||||
characterCreateDateRangeLowerHr = table->getIntValue(columnCharacterCreateDateRangeLowerHr, i);
|
||||
characterCreateDateRangeLowerMin = table->getIntValue(columnCharacterCreateDateRangeLowerMin, i);
|
||||
characterCreateDateRangeLowerSec = table->getIntValue(columnCharacterCreateDateRangeLowerSec, i);
|
||||
|
||||
characterCreateDateRangeUpperYr = table->getIntValue(columnCharacterCreateDateRangeUpperYr, i);
|
||||
characterCreateDateRangeUpperMo = table->getIntValue(columnCharacterCreateDateRangeUpperMo, i);
|
||||
characterCreateDateRangeUpperDy = table->getIntValue(columnCharacterCreateDateRangeUpperDy, i);
|
||||
characterCreateDateRangeUpperHr = table->getIntValue(columnCharacterCreateDateRangeUpperHr, i);
|
||||
characterCreateDateRangeUpperMin = table->getIntValue(columnCharacterCreateDateRangeUpperMin, i);
|
||||
characterCreateDateRangeUpperSec = table->getIntValue(columnCharacterCreateDateRangeUpperSec, i);
|
||||
|
||||
freeCtsInfo.targetCluster.clear();
|
||||
freeCtsInfo.startTime = -1;
|
||||
freeCtsInfo.endTime = -1;
|
||||
freeCtsInfo.sourceCharacterCreateTimeLower = -1;
|
||||
freeCtsInfo.sourceCharacterCreateTimeUpper = -1;
|
||||
|
||||
if ((startDateYr > 0) && (startDateMo > 0) && (startDateDy > 0))
|
||||
{
|
||||
freeCtsInfo.startTime = convertToEpoch(startDateYr, startDateMo, startDateDy, startDateHr, startDateMin, startDateSec);
|
||||
FATAL((freeCtsInfo.startTime <= 0), ("date %d/%d/%d %d:%d:%d on row %d is invalid", startDateMo, startDateDy, startDateYr, startDateHr, startDateMin, startDateSec, (i+3)));
|
||||
}
|
||||
|
||||
if ((endDateYr > 0) && (endDateMo > 0) && (endDateDy > 0))
|
||||
{
|
||||
freeCtsInfo.endTime = convertToEpoch(endDateYr, endDateMo, endDateDy, endDateHr, endDateMin, endDateSec);
|
||||
FATAL((freeCtsInfo.endTime <= 0), ("date %d/%d/%d %d:%d:%d on row %d is invalid", endDateMo, endDateDy, endDateYr, endDateHr, endDateMin, endDateSec, (i+3)));
|
||||
}
|
||||
|
||||
if ((freeCtsInfo.startTime > 0) && (freeCtsInfo.endTime > 0))
|
||||
{
|
||||
FATAL((freeCtsInfo.startTime >= freeCtsInfo.endTime), ("start date (%s) must be before end date (%s) on row %d", CalendarTime::convertEpochToTimeStringLocal(freeCtsInfo.startTime).c_str(), CalendarTime::convertEpochToTimeStringLocal(freeCtsInfo.endTime).c_str(), (i+3)));
|
||||
}
|
||||
|
||||
if ((characterCreateDateRangeLowerYr > 0) && (characterCreateDateRangeLowerMo > 0) && (characterCreateDateRangeLowerDy > 0))
|
||||
{
|
||||
freeCtsInfo.sourceCharacterCreateTimeLower = convertToEpoch(characterCreateDateRangeLowerYr, characterCreateDateRangeLowerMo, characterCreateDateRangeLowerDy, characterCreateDateRangeLowerHr, characterCreateDateRangeLowerMin, characterCreateDateRangeLowerSec);
|
||||
FATAL((freeCtsInfo.sourceCharacterCreateTimeLower <= 0), ("date %d/%d/%d %d:%d:%d on row %d is invalid", characterCreateDateRangeLowerMo, characterCreateDateRangeLowerDy, characterCreateDateRangeLowerYr, characterCreateDateRangeLowerHr, characterCreateDateRangeLowerMin, characterCreateDateRangeLowerSec, (i+3)));
|
||||
}
|
||||
|
||||
if ((characterCreateDateRangeUpperYr > 0) && (characterCreateDateRangeUpperMo > 0) && (characterCreateDateRangeUpperDy > 0))
|
||||
{
|
||||
freeCtsInfo.sourceCharacterCreateTimeUpper = convertToEpoch(characterCreateDateRangeUpperYr, characterCreateDateRangeUpperMo, characterCreateDateRangeUpperDy, characterCreateDateRangeUpperHr, characterCreateDateRangeUpperMin, characterCreateDateRangeUpperSec);
|
||||
FATAL((freeCtsInfo.sourceCharacterCreateTimeUpper <= 0), ("date %d/%d/%d %d:%d:%d on row %d is invalid", characterCreateDateRangeUpperMo, characterCreateDateRangeUpperDy, characterCreateDateRangeUpperYr, characterCreateDateRangeUpperHr, characterCreateDateRangeUpperMin, characterCreateDateRangeUpperSec, (i+3)));
|
||||
}
|
||||
|
||||
if ((freeCtsInfo.sourceCharacterCreateTimeLower > 0) && (freeCtsInfo.sourceCharacterCreateTimeUpper > 0))
|
||||
{
|
||||
FATAL((freeCtsInfo.sourceCharacterCreateTimeLower >= freeCtsInfo.sourceCharacterCreateTimeUpper), ("lower date (%s) must be before upper date (%s) on row %d", CalendarTime::convertEpochToTimeStringLocal(freeCtsInfo.sourceCharacterCreateTimeLower).c_str(), CalendarTime::convertEpochToTimeStringLocal(freeCtsInfo.sourceCharacterCreateTimeUpper).c_str(), (i+3)));
|
||||
}
|
||||
|
||||
tokensSourceClusterList.clear();
|
||||
tokensTargetClusterList.clear();
|
||||
if (Unicode::tokenize(Unicode::narrowToWide(sourceClusterList), tokensSourceClusterList, &clusterListDelimiters, NULL) && (tokensSourceClusterList.size() > 0) && Unicode::tokenize(Unicode::narrowToWide(targetClusterList), tokensTargetClusterList, &clusterListDelimiters, NULL) && (tokensTargetClusterList.size() > 0))
|
||||
{
|
||||
for (tokensIter = tokensTargetClusterList.begin(); tokensIter != tokensTargetClusterList.end(); ++tokensIter)
|
||||
freeCtsInfo.targetCluster[Unicode::wideToNarrow(Unicode::toLower(*tokensIter))] = Unicode::wideToNarrow(*tokensIter);
|
||||
|
||||
for (tokensIter = tokensSourceClusterList.begin(); tokensIter != tokensSourceClusterList.end(); ++tokensIter)
|
||||
IGNORE_RETURN(s_freeCtsList.insert(std::make_pair(Unicode::wideToNarrow(Unicode::toLower(*tokensIter)), freeCtsInfo)));
|
||||
}
|
||||
}
|
||||
|
||||
DataTableManager::close(s_freeCtsFileName);
|
||||
|
||||
#ifdef _DEBUG
|
||||
for (std::multimap<std::string, FreeCtsDataTable::FreeCtsInfo>::const_iterator iter = s_freeCtsList.begin(); iter != s_freeCtsList.end(); ++iter)
|
||||
{
|
||||
std::string targetClusters;
|
||||
for (std::map<std::string, std::string>::const_iterator iter2 = iter->second.targetCluster.begin(); iter2 != iter->second.targetCluster.end(); ++iter2)
|
||||
{
|
||||
if (!targetClusters.empty())
|
||||
targetClusters += ", ";
|
||||
|
||||
targetClusters += iter2->first;
|
||||
}
|
||||
|
||||
std::string startDate("NA");
|
||||
std::string endDate("NA");
|
||||
|
||||
if (iter->second.startTime > 0)
|
||||
startDate = CalendarTime::convertEpochToTimeStringLocal(iter->second.startTime);
|
||||
|
||||
if (iter->second.endTime > 0)
|
||||
endDate = CalendarTime::convertEpochToTimeStringLocal(iter->second.endTime);
|
||||
|
||||
std::string characterCreateDateLower("NA");
|
||||
std::string characterCreateDateUpper("NA");
|
||||
|
||||
if (iter->second.sourceCharacterCreateTimeLower > 0)
|
||||
characterCreateDateLower = CalendarTime::convertEpochToTimeStringLocal(iter->second.sourceCharacterCreateTimeLower);
|
||||
|
||||
if (iter->second.sourceCharacterCreateTimeUpper > 0)
|
||||
characterCreateDateUpper = CalendarTime::convertEpochToTimeStringLocal(iter->second.sourceCharacterCreateTimeUpper);
|
||||
|
||||
DEBUG_REPORT_LOG(true, ("FreeCtsInfo rule=(%s, %s), source cluster=(%s) target clusters=(%s) start/end=(%ld, %s) -> (%ld, %s) character create date=(%ld, %s) -> (%ld, %s)\n", iter->second.ruleName.c_str(), iter->second.ruleDescription.c_str(), iter->first.c_str(), targetClusters.c_str(), iter->second.startTime, startDate.c_str(), iter->second.endTime, endDate.c_str(), iter->second.sourceCharacterCreateTimeLower, characterCreateDateLower.c_str(), iter->second.sourceCharacterCreateTimeUpper, characterCreateDateUpper.c_str()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
time_t FreeCtsDataTableNamespace::convertToEpoch(int const year, int const month, int const day, int const hour, int const minute, int const second)
|
||||
{
|
||||
time_t const timeNow = ::time(NULL);
|
||||
struct tm * timeinfo = ::localtime(&timeNow);
|
||||
FATAL(!timeinfo, ("::localtime() returns NULL"));
|
||||
|
||||
// greater than zero if Daylight Saving Time is in effect,
|
||||
// zero if Daylight Saving Time is not in effect,
|
||||
// and less than zero if the information is not available.
|
||||
int const currentTimeIsDst = timeinfo->tm_isdst;
|
||||
|
||||
timeinfo->tm_year = year - 1900;
|
||||
timeinfo->tm_mon = month - 1;
|
||||
timeinfo->tm_mday = day;
|
||||
timeinfo->tm_hour = hour;
|
||||
timeinfo->tm_min = minute;
|
||||
timeinfo->tm_sec = second;
|
||||
|
||||
time_t convertedTime = ::mktime(timeinfo);
|
||||
|
||||
if (convertedTime <= 0)
|
||||
{
|
||||
return convertedTime;
|
||||
}
|
||||
|
||||
// if the converted time converted back to y/m/d h:m:s doesn't
|
||||
// match the y/m/d h:m:s that is passed in, it probably means
|
||||
// the passed in time is in a different standard/daylight period
|
||||
// than the current time, so try the conversion again with the
|
||||
// "opposite" standard/daylight period than the current time,
|
||||
// and it should be OK
|
||||
timeinfo = ::localtime(&convertedTime);
|
||||
FATAL(!timeinfo, ("::localtime() returns NULL"));
|
||||
|
||||
if ((timeinfo->tm_year != (year - 1900)) ||
|
||||
(timeinfo->tm_mon != (month - 1)) ||
|
||||
(timeinfo->tm_mday != day) ||
|
||||
(timeinfo->tm_hour != hour) ||
|
||||
(timeinfo->tm_min != minute) ||
|
||||
(timeinfo->tm_sec != second))
|
||||
{
|
||||
if (currentTimeIsDst >= 0)
|
||||
{
|
||||
timeinfo->tm_year = year - 1900;
|
||||
timeinfo->tm_mon = month - 1;
|
||||
timeinfo->tm_mday = day;
|
||||
timeinfo->tm_hour = hour;
|
||||
timeinfo->tm_min = minute;
|
||||
timeinfo->tm_sec = second;
|
||||
timeinfo->tm_isdst = ((currentTimeIsDst == 0) ? 1 : 0);
|
||||
|
||||
convertedTime = ::mktime(timeinfo);
|
||||
}
|
||||
}
|
||||
|
||||
return convertedTime;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
std::string const & FreeCtsDataTable::getFreeCtsFileName()
|
||||
{
|
||||
if (!s_dataLoaded)
|
||||
loadData();
|
||||
|
||||
return s_freeCtsFileName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
std::multimap<std::string, FreeCtsDataTable::FreeCtsInfo> const & FreeCtsDataTable::getFreeCtsInfo()
|
||||
{
|
||||
if (!s_dataLoaded)
|
||||
loadData();
|
||||
|
||||
return s_freeCtsList;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
FreeCtsDataTable::FreeCtsInfo const * FreeCtsDataTable::isFreeCtsSourceCluster(std::string const & sourceCluster)
|
||||
{
|
||||
if (!s_dataLoaded)
|
||||
loadData();
|
||||
|
||||
if (s_freeCtsList.empty())
|
||||
return NULL;
|
||||
|
||||
time_t const timeNow = ::time(NULL);
|
||||
std::pair<std::multimap<std::string, FreeCtsInfo>::const_iterator, std::multimap<std::string, FreeCtsInfo>::const_iterator> range = s_freeCtsList.equal_range(Unicode::toLower(sourceCluster));
|
||||
for (std::multimap<std::string, FreeCtsInfo>::const_iterator iter = range.first; iter != range.second; ++iter)
|
||||
{
|
||||
bool const satisfyStartTime = ((iter->second.startTime <= 0) || (timeNow >= iter->second.startTime));
|
||||
bool const satisfyEndTime = ((iter->second.endTime <= 0) || (timeNow <= iter->second.endTime));
|
||||
|
||||
if (satisfyStartTime && satisfyEndTime)
|
||||
return &(iter->second);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
FreeCtsDataTable::FreeCtsInfo const * FreeCtsDataTable::wouldCharacterTransferBeFree(time_t const sourceCharacterCreateTime, uint32 const sourceStationId, std::string const & sourceCluster, uint32 const targetStationId, std::string const & targetCluster, bool ignoreTimeRestriction)
|
||||
{
|
||||
if (!s_dataLoaded)
|
||||
loadData();
|
||||
|
||||
if (s_freeCtsList.empty())
|
||||
return NULL;
|
||||
|
||||
if ((sourceCharacterCreateTime <= 0) && !ignoreTimeRestriction)
|
||||
return NULL;
|
||||
|
||||
if (sourceStationId != targetStationId)
|
||||
return NULL;
|
||||
|
||||
time_t const timeNow = ::time(NULL);
|
||||
|
||||
std::string const lowerTargetCluster(Unicode::toLower(targetCluster));
|
||||
std::pair<std::multimap<std::string, FreeCtsInfo>::const_iterator, std::multimap<std::string, FreeCtsInfo>::const_iterator> range = s_freeCtsList.equal_range(Unicode::toLower(sourceCluster));
|
||||
for (std::multimap<std::string, FreeCtsInfo>::const_iterator iter = range.first; iter != range.second; ++iter)
|
||||
{
|
||||
if (iter->second.targetCluster.count(lowerTargetCluster) > 0)
|
||||
{
|
||||
if (ignoreTimeRestriction)
|
||||
return &(iter->second);
|
||||
|
||||
bool const satisfyStartTime = ((iter->second.startTime <= 0) || (timeNow >= iter->second.startTime));
|
||||
bool const satisfyEndTime = ((iter->second.endTime <= 0) || (timeNow <= iter->second.endTime));
|
||||
|
||||
bool const satisfyCreateTimeLowerBound = ((iter->second.sourceCharacterCreateTimeLower <= 0) || (sourceCharacterCreateTime >= iter->second.sourceCharacterCreateTimeLower));
|
||||
bool const satisfyCreateTimeUpperBound = ((iter->second.sourceCharacterCreateTimeUpper <= 0) || (sourceCharacterCreateTime <= iter->second.sourceCharacterCreateTimeUpper));
|
||||
|
||||
if (satisfyStartTime && satisfyEndTime && satisfyCreateTimeLowerBound && satisfyCreateTimeUpperBound)
|
||||
return &(iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
FreeCtsDataTable::FreeCtsInfo const * FreeCtsDataTable::getFreeCtsInfoForCharacter(time_t const sourceCharacterCreateTime, std::string const & sourceCluster, bool ignoreTimeRestriction)
|
||||
{
|
||||
if (!s_dataLoaded)
|
||||
loadData();
|
||||
|
||||
if (s_freeCtsList.empty())
|
||||
return NULL;
|
||||
|
||||
if ((sourceCharacterCreateTime <= 0) && !ignoreTimeRestriction)
|
||||
return NULL;
|
||||
|
||||
time_t const timeNow = ::time(NULL);
|
||||
std::pair<std::multimap<std::string, FreeCtsInfo>::const_iterator, std::multimap<std::string, FreeCtsInfo>::const_iterator> range = s_freeCtsList.equal_range(Unicode::toLower(sourceCluster));
|
||||
for (std::multimap<std::string, FreeCtsInfo>::const_iterator iter = range.first; iter != range.second; ++iter)
|
||||
{
|
||||
if (ignoreTimeRestriction)
|
||||
return &(iter->second);
|
||||
|
||||
bool const satisfyStartTime = ((iter->second.startTime <= 0) || (timeNow >= iter->second.startTime));
|
||||
bool const satisfyEndTime = ((iter->second.endTime <= 0) || (timeNow <= iter->second.endTime));
|
||||
|
||||
bool const satisfyCreateTimeLowerBound = ((iter->second.sourceCharacterCreateTimeLower <= 0) || (sourceCharacterCreateTime >= iter->second.sourceCharacterCreateTimeLower));
|
||||
bool const satisfyCreateTimeUpperBound = ((iter->second.sourceCharacterCreateTimeUpper <= 0) || (sourceCharacterCreateTime <= iter->second.sourceCharacterCreateTimeUpper));
|
||||
|
||||
if (satisfyStartTime && satisfyEndTime && satisfyCreateTimeLowerBound && satisfyCreateTimeUpperBound)
|
||||
return &(iter->second);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FreeCtsDataTable.h
|
||||
// Copyright 2006 Sony Online Entertainment LLC (SOE)
|
||||
// All rights reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_FreeCtsDataTable_H
|
||||
#define INCLUDED_FreeCtsDataTable_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class FreeCtsDataTable // static class
|
||||
{
|
||||
public:
|
||||
|
||||
struct FreeCtsInfo
|
||||
{
|
||||
std::string ruleName;
|
||||
std::string ruleDescription;
|
||||
std::map<std::string, std::string> targetCluster;
|
||||
time_t startTime;
|
||||
time_t endTime;
|
||||
time_t sourceCharacterCreateTimeLower;
|
||||
time_t sourceCharacterCreateTimeUpper;
|
||||
};
|
||||
|
||||
static std::string const & getFreeCtsFileName();
|
||||
static stdmultimap<std::string, FreeCtsDataTable::FreeCtsInfo>::fwd const & getFreeCtsInfo();
|
||||
static FreeCtsDataTable::FreeCtsInfo const * isFreeCtsSourceCluster(std::string const & sourceCluster);
|
||||
static FreeCtsDataTable::FreeCtsInfo const * wouldCharacterTransferBeFree(time_t sourceCharacterCreateTime, uint32 sourceStationId, std::string const & sourceCluster, uint32 targetStationId, std::string const & targetCluster, bool ignoreTimeRestriction);
|
||||
static FreeCtsDataTable::FreeCtsInfo const * getFreeCtsInfoForCharacter(time_t sourceCharacterCreateTime, std::string const & sourceCluster, bool ignoreTimeRestriction);
|
||||
|
||||
private: // disabled
|
||||
|
||||
FreeCtsDataTable();
|
||||
FreeCtsDataTable(FreeCtsDataTable const &);
|
||||
FreeCtsDataTable &operator =(FreeCtsDataTable const &);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // INCLUDED_FreeCtsDataTable_H
|
||||
@@ -0,0 +1,39 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// LocationData.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/LocationData.h"
|
||||
|
||||
#include "sharedMathArchive/VectorArchive.h"
|
||||
#include "unicodeArchive/UnicodeArchive.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
void get(ReadIterator & source, LocationData & target)
|
||||
{
|
||||
get(source, target.scene);
|
||||
Vector center;
|
||||
float radius;
|
||||
get(source, center);
|
||||
get(source, radius);
|
||||
target.location.setCenter(center);
|
||||
target.location.setRadius(radius);
|
||||
get(source, target.name);
|
||||
}
|
||||
|
||||
void put(ByteStream & target, const LocationData & source)
|
||||
{
|
||||
put(target, source.scene);
|
||||
put(target, source.location.getCenter());
|
||||
put(target, source.location.getRadius());
|
||||
put(target, source.name);
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,51 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// LocationData.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_LocationData_H
|
||||
#define INCLUDED_LocationData_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "Archive/AutoByteStream.h"
|
||||
#include "sharedMath/Sphere.h"
|
||||
#include "Unicode.h"
|
||||
//#include "sharedFoundation/NetworkId.h"
|
||||
//#include "sharedMath/Vector.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/* namespace DB */
|
||||
/* { */
|
||||
/* class BindableDouble; */
|
||||
/* template <int S> */
|
||||
/* class BindableString; */
|
||||
/* } */
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class LocationData
|
||||
{
|
||||
public:
|
||||
Sphere location;
|
||||
Unicode::String name;
|
||||
std::string scene;
|
||||
|
||||
inline bool operator==(const LocationData & rhs) const
|
||||
{
|
||||
return this == &rhs || (scene == rhs.scene && location == rhs.location && name == rhs.name);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
void get(ReadIterator & source, LocationData & target);
|
||||
void put(ByteStream & target, const LocationData & source);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MissionLocation.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/MissionLocation.h"
|
||||
|
||||
#include "localizationArchive/StringIdArchive.h"
|
||||
#include "sharedMathArchive/VectorArchive.h"
|
||||
#include "sharedFoundation/NetworkIdArchive.h"
|
||||
#include "unicodeArchive/UnicodeArchive.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
|
||||
void get(ReadIterator & source, MissionLocation & target)
|
||||
{
|
||||
get(source, target.coordinates);
|
||||
get(source, target.planetName);
|
||||
get(source, target.regionName);
|
||||
get(source, target.cell);
|
||||
}
|
||||
|
||||
void put(ByteStream & target, const MissionLocation & source)
|
||||
{
|
||||
put(target, source.coordinates);
|
||||
put(target, source.planetName);
|
||||
put(target, source.regionName);
|
||||
put(target, source.cell);
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,72 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MissionLocation.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_MissionLocation_H
|
||||
#define INCLUDED_MissionLocation_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "Archive/AutoByteStream.h"
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
#include "sharedMath/Vector.h"
|
||||
#include "StringId.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace DB
|
||||
{
|
||||
class BindableDouble;
|
||||
template <int S>
|
||||
class BindableString;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
//Todo: Generalize this into an all-purpose Location class
|
||||
class MissionLocation
|
||||
{
|
||||
public:
|
||||
Vector coordinates;
|
||||
std::string planetName;
|
||||
Unicode::String regionName;
|
||||
NetworkId cell;
|
||||
|
||||
public:
|
||||
bool operator== (const MissionLocation &rhs) const;
|
||||
bool operator!= (const MissionLocation &rhs) const;
|
||||
|
||||
public:
|
||||
//@todo: (un)pack cell
|
||||
void unpackFromDatabase(const DB::BindableDouble &x,const DB::BindableDouble &y, const DB::BindableDouble &z, const DB::BindableString<500> &planet, const DB::BindableString<500> ®ion_name, const DB::BindableNetworkId &cell);
|
||||
void packToDatabase(DB::BindableDouble &x,DB::BindableDouble &y, DB::BindableDouble &z, DB::BindableString<500> &planet, DB::BindableString<500> ®ion_name, DB::BindableNetworkId &cell) const;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline bool MissionLocation::operator== (const MissionLocation &rhs) const
|
||||
{
|
||||
return ((coordinates == rhs.coordinates) && (planetName == rhs.planetName) && (regionName == rhs.regionName) && (cell == rhs.cell));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool MissionLocation::operator!= (const MissionLocation &rhs) const
|
||||
{
|
||||
return !(MissionLocation::operator==(rhs));
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
void get(ReadIterator & source, MissionLocation & target);
|
||||
void put(ByteStream & target, const MissionLocation & source);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,147 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PopulationList.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/PopulationList.h"
|
||||
|
||||
#include "Archive/AutoByteStream.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
PopulationList::PopulationList()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
PopulationList::~PopulationList()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PopulationList::setPopulation(const std::string &scene, int x, int z, int population)
|
||||
{
|
||||
m_populationMap[Location(scene,x,z)]=population;
|
||||
m_populationCache.clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int PopulationList::getNearestPopulation(const std::string &scene, int x, int z) const
|
||||
{
|
||||
Location where(scene,x,z);
|
||||
PopulationMapType::const_iterator i=m_populationMap.find(where);
|
||||
if (i!=m_populationMap.end())
|
||||
return i->second;
|
||||
else
|
||||
{
|
||||
i=m_populationCache.find(where);
|
||||
if (i!=m_populationCache.end())
|
||||
return i->second;
|
||||
else
|
||||
{
|
||||
int closestSoFar=-1;
|
||||
int population=0;
|
||||
for (i=m_populationMap.begin(); i!=m_populationMap.end(); ++i)
|
||||
{
|
||||
if (i->first.getScene()==scene)
|
||||
{
|
||||
int distX=x - i->first.getX();
|
||||
int distZ=z - i->first.getZ();
|
||||
int distSquared = (distX*distX)+(distZ*distZ);
|
||||
if (closestSoFar==-1 || distSquared < closestSoFar)
|
||||
{
|
||||
closestSoFar = distSquared;
|
||||
population = i->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_populationCache.insert(std::make_pair<Location, int>(where,population));
|
||||
return population;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PopulationList::update(const PopulationList &newData)
|
||||
{
|
||||
for (PopulationMapType::const_iterator i=newData.m_populationMap.begin(); i!=newData.m_populationMap.end(); ++i)
|
||||
{
|
||||
setPopulation(i->first.getScene(), i->first.getX(), i->first.getZ(), i->second);
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
PopulationList::Location::Location(const std::string &scene, int x, int z) :
|
||||
m_scene(scene),
|
||||
m_x(x),
|
||||
m_z(z)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool PopulationList::Location::operator<(const Location &rhs) const
|
||||
{
|
||||
if (m_z < rhs.m_z)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
if (m_z == rhs.m_z)
|
||||
{
|
||||
if (m_x < rhs.m_x)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
if (m_x == rhs.m_x)
|
||||
return (m_scene < rhs.m_scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
void get(ReadIterator & source, PopulationList & target)
|
||||
{
|
||||
size_t numEntries;
|
||||
get(source,numEntries);
|
||||
for (size_t count=0; count < numEntries; ++count)
|
||||
{
|
||||
std::string scene;
|
||||
int x;
|
||||
int z;
|
||||
int population;
|
||||
get(source,scene);
|
||||
get(source,x);
|
||||
get(source,z);
|
||||
get(source,population);
|
||||
target.setPopulation(scene,x,z,population);
|
||||
}
|
||||
}
|
||||
|
||||
void put(ByteStream & target, const PopulationList & source)
|
||||
{
|
||||
put(target,source.m_populationMap.size());
|
||||
for (PopulationList::PopulationMapType::const_iterator i=source.m_populationMap.begin(); i!=source.m_populationMap.end(); ++i)
|
||||
{
|
||||
put(target,i->first.getScene());
|
||||
put(target,i->first.getX());
|
||||
put(target,i->first.getZ());
|
||||
put(target,i->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,100 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PopulationList.h
|
||||
// copyright (c) 2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PopulationList_H
|
||||
#define INCLUDED_PopulationList_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class PopulationList;
|
||||
namespace Archive
|
||||
{
|
||||
class ReadIterator;
|
||||
class ByteStream;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
void get(ReadIterator & source, PopulationList & target);
|
||||
void put(ByteStream & target, const PopulationList & source);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* A class that manages a list of locations and the number of players
|
||||
* in each location.
|
||||
*/
|
||||
|
||||
class PopulationList
|
||||
{
|
||||
public:
|
||||
PopulationList();
|
||||
~PopulationList();
|
||||
|
||||
public:
|
||||
void setPopulation(const std::string &scene, int x, int z, int population);
|
||||
int getNearestPopulation(const std::string &scene, int x, int z) const;
|
||||
void update(const PopulationList &newData);
|
||||
|
||||
private:
|
||||
class Location
|
||||
{
|
||||
public:
|
||||
Location(const std::string &scene, int x, int z);
|
||||
bool operator< (const Location &rhs) const;
|
||||
|
||||
public:
|
||||
const std::string &getScene() const;
|
||||
int getX() const;
|
||||
int getZ() const;
|
||||
|
||||
private:
|
||||
std::string m_scene;
|
||||
int m_x;
|
||||
int m_z;
|
||||
};
|
||||
|
||||
typedef std::map<Location, int> PopulationMapType;
|
||||
PopulationMapType m_populationMap;
|
||||
mutable PopulationMapType m_populationCache;
|
||||
|
||||
friend void Archive::get(ReadIterator & source, PopulationList & target);
|
||||
friend void Archive::put(ByteStream & target, const PopulationList & source);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline const std::string &PopulationList::Location::getScene() const
|
||||
{
|
||||
return m_scene;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline int PopulationList::Location::getX() const
|
||||
{
|
||||
return m_x;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline int PopulationList::Location::getZ() const
|
||||
{
|
||||
return m_z;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PvpEnemy.cpp
|
||||
//
|
||||
// Copyright 2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/PvpEnemy.h"
|
||||
#include "Archive/Archive.h"
|
||||
#include "Archive/ByteStream.h"
|
||||
#include "sharedFoundation/NetworkIdArchive.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void put(Archive::ByteStream &target, PvpEnemy const &source)
|
||||
{
|
||||
put(target, source.enemyId);
|
||||
put(target, source.enemyFaction);
|
||||
put(target, source.expireTime);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void get(Archive::ReadIterator &source, PvpEnemy &target)
|
||||
{
|
||||
get(source, target.enemyId);
|
||||
get(source, target.enemyFaction);
|
||||
get(source, target.expireTime);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PvpEnemy.h
|
||||
//
|
||||
// Copyright 2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef _PvpEnemy_H
|
||||
#define _PvpEnemy_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
struct PvpEnemy
|
||||
{
|
||||
PvpEnemy() :
|
||||
enemyId(NetworkId::cms_invalid),
|
||||
enemyFaction(0),
|
||||
expireTime(0)
|
||||
{
|
||||
}
|
||||
|
||||
PvpEnemy(NetworkId const &id, uint32 faction, int time) :
|
||||
enemyId(id),
|
||||
enemyFaction(faction),
|
||||
expireTime(time)
|
||||
{
|
||||
}
|
||||
|
||||
NetworkId enemyId;
|
||||
uint32 enemyFaction;
|
||||
int expireTime;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool operator==(PvpEnemy const &lhs, PvpEnemy const &rhs)
|
||||
{
|
||||
return lhs.expireTime == rhs.expireTime
|
||||
&& lhs.enemyId == rhs.enemyId
|
||||
&& lhs.enemyFaction == rhs.enemyFaction;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
class ByteStream;
|
||||
class ReadIterator;
|
||||
|
||||
void put(Archive::ByteStream &target, PvpEnemy const &source);
|
||||
void get(Archive::ReadIterator &source, PvpEnemy &target);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // _PvpEnemy_H
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecentMaxSyncedValue.cpp
|
||||
//
|
||||
// Copyright 2004 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/RecentMaxSyncedValue.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace RecentMaxSyncedValueNamespace
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int syncStampLongDeltaTime(uint32 stamp1, uint32 stamp2)
|
||||
{
|
||||
uint32 const delta = stamp1 - stamp2;
|
||||
if (delta > 0x7fffffff)
|
||||
return static_cast<int>(0xffffffff-delta);
|
||||
return static_cast<int>(delta);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
using namespace RecentMaxSyncedValueNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
RecentMaxSyncedValue::RecentMaxSyncedValue(float value, int checkIntervalMs, int fudgeIntervalMs) :
|
||||
m_maximum(value),
|
||||
m_oldMaximum(value),
|
||||
m_changeSyncStamp(0),
|
||||
m_checkIntervalMs(checkIntervalMs),
|
||||
m_fudgeIntervalMs(fudgeIntervalMs)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
float RecentMaxSyncedValue::getLastSetValue() const
|
||||
{
|
||||
return m_maximum;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
float RecentMaxSyncedValue::getRecentMaximum(uint32 curSyncStamp)
|
||||
{
|
||||
// If we have reduced the maximum recently, see if we're still in the
|
||||
// interval we allow for keeping old maximums around, and if so,
|
||||
// use the faster max speed. If we have passed the end of the
|
||||
// interval, clear the stamp so we don't have to check it anymore.
|
||||
if (m_changeSyncStamp)
|
||||
{
|
||||
int const fudgeTime = m_checkIntervalMs + m_fudgeIntervalMs;
|
||||
if (syncStampLongDeltaTime(m_changeSyncStamp, curSyncStamp) < fudgeTime)
|
||||
return m_oldMaximum;
|
||||
m_changeSyncStamp = 0;
|
||||
}
|
||||
return m_maximum;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void RecentMaxSyncedValue::setValue(float value, uint32 curSyncStamp)
|
||||
{
|
||||
if (value >= getRecentMaximum(curSyncStamp))
|
||||
{
|
||||
// If we are setting a maximum higher than our current effective maximum,
|
||||
// just clear the sync stamp.
|
||||
m_changeSyncStamp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're reducing our maximum, so we need to preserve our old maximum to
|
||||
// deal with usage in the time following the change. We also need to
|
||||
// deal with reducing the maximum multiple times in a short interval.
|
||||
|
||||
// m_maximum is our previous maximum. We know that the new maximum being
|
||||
// set is less than this value from the previous check, so the maximum
|
||||
// is being reduced.
|
||||
|
||||
// m_oldMaximum was our previous old maximum, being kept around to make
|
||||
// sure we're being liberal when determining what the maximum possible
|
||||
// value over a given time interval should be.
|
||||
|
||||
// 1) If our previous maximum is greater than our previous old maximum,
|
||||
// or we don't have a previous old maximum, we push the previous
|
||||
// maximum into the old maximum for future use.
|
||||
// 2) Otherwise, we have an old maximum greater than our previous
|
||||
// maximum, so we want to lower the old maximum iff more time has
|
||||
// elapsed than we allow for keeping old maximums around. Not doing
|
||||
// this could allow us to lower the maximum too quickly.
|
||||
if ( m_maximum >= m_oldMaximum
|
||||
|| !m_changeSyncStamp
|
||||
|| syncStampLongDeltaTime(m_changeSyncStamp, curSyncStamp) >= m_fudgeIntervalMs)
|
||||
m_oldMaximum = m_maximum;
|
||||
m_changeSyncStamp = curSyncStamp;
|
||||
}
|
||||
m_maximum = value;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecentMaxSyncedValue.h
|
||||
//
|
||||
// Copyright 2004 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_RecentMaxSyncedValue_H
|
||||
#define INCLUDED_RecentMaxSyncedValue_H
|
||||
|
||||
class RecentMaxSyncedValue
|
||||
{
|
||||
public:
|
||||
RecentMaxSyncedValue(float value, int checkIntervalMs, int fudgeIntervalMs);
|
||||
float getLastSetValue() const;
|
||||
float getRecentMaximum(uint32 curSyncStamp);
|
||||
void setValue(float value, uint32 curSyncStamp);
|
||||
|
||||
private:
|
||||
RecentMaxSyncedValue();
|
||||
RecentMaxSyncedValue(RecentMaxSyncedValue const &);
|
||||
RecentMaxSyncedValue &operator=(RecentMaxSyncedValue const &);
|
||||
|
||||
float m_maximum;
|
||||
float m_oldMaximum;
|
||||
uint32 m_changeSyncStamp;
|
||||
int const m_checkIntervalMs;
|
||||
int const m_fudgeIntervalMs;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // INCLUDED_RecentMaxSyncedValue_H
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ResourceFractalData.cpp
|
||||
// copyright (c) 2004 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/ResourceFractalData.h"
|
||||
|
||||
#include "Archive/AutoByteStream.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
ResourceFractalData::ResourceFractalData() :
|
||||
m_scaleX(0.0f),
|
||||
m_scaleY(0.0f),
|
||||
m_bias(0.0f),
|
||||
m_gain(0.0f),
|
||||
m_combinationRule(0),
|
||||
m_frequency(0.0f),
|
||||
m_amplitude(0.0f),
|
||||
m_octaves(0)
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,32 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ResourceFractalData.h
|
||||
// copyright (c) 2004 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ResourceFractalData_H
|
||||
#define INCLUDED_ResourceFractalData_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* Fractal parameters for resource pools
|
||||
*/
|
||||
struct ResourceFractalData
|
||||
{
|
||||
float m_scaleX;
|
||||
float m_scaleY;
|
||||
float m_bias;
|
||||
float m_gain;
|
||||
int m_combinationRule;
|
||||
float m_frequency;
|
||||
float m_amplitude;
|
||||
int m_octaves;
|
||||
|
||||
ResourceFractalData();
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
// ServerClock.cpp
|
||||
// copyright 2001 Verant Interactive
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/ServerClock.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const unsigned long ServerClock::cms_endOfTime = static_cast<unsigned long>(-1);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ServerClock::ServerClock() :
|
||||
serverFrame(0),
|
||||
subtractInterval(0),
|
||||
lastTime(time(0))
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ServerClock::~ServerClock()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const unsigned long ServerClock::getGameTimeSeconds() const
|
||||
{
|
||||
FATAL(!isSet(), ("ServerClock::getGameTimeSeconds: Clock was not set."));
|
||||
return int(lastTime - subtractInterval);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ServerClock::incrementServerFrame()
|
||||
{
|
||||
const time_t currentTime = time(0);
|
||||
|
||||
if (currentTime < lastTime-120 || currentTime > lastTime+120)
|
||||
LOG("ServerClock", ("Clock changed by more than 120 seconds in a frame (%lu to %lu)!", lastTime, currentTime));
|
||||
lastTime = currentTime;
|
||||
|
||||
serverFrame++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ServerClock::setSubtractInterval(const unsigned long newSubtractInterval)
|
||||
{
|
||||
subtractInterval = newSubtractInterval;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ServerClock::setGameTimeSeconds(const unsigned long newGameTime)
|
||||
{
|
||||
subtractInterval = int(time(0) - newGameTime);
|
||||
LOG("ServerClock", ("Game time set to %lu (subtract interval %lu)", newGameTime, subtractInterval));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ServerClock &ServerClock::getInstance()
|
||||
{
|
||||
static ServerClock theInstance;
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Given a time in seconds, make a string that expresses how long it is.
|
||||
* For debug output only. In English, not localized. Not thread-safe.
|
||||
*/
|
||||
std::string ServerClock::getDebugPrintableTimeframe(unsigned long const timeInSeconds)
|
||||
{
|
||||
unsigned long const dayInSeconds = 60 * 60 * 24;
|
||||
unsigned long const hourInSeconds = 60 * 60;
|
||||
unsigned long const minuteInSeconds = 60;
|
||||
|
||||
static char buffer[256];
|
||||
|
||||
if (timeInSeconds > dayInSeconds)
|
||||
{
|
||||
snprintf(buffer, 256, "~ %lu days", timeInSeconds / dayInSeconds);
|
||||
}
|
||||
else if (timeInSeconds > hourInSeconds)
|
||||
{
|
||||
snprintf(buffer, 256, "~ %lu hours", timeInSeconds / hourInSeconds);
|
||||
}
|
||||
else if (timeInSeconds > minuteInSeconds)
|
||||
{
|
||||
snprintf(buffer, 256, "~ %lu minutes", timeInSeconds / minuteInSeconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buffer, 256, "%lu seconds", timeInSeconds);
|
||||
}
|
||||
|
||||
buffer[255]='\0';
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// ServerClock.h
|
||||
// copyright 2001 Verant Interactive
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class ServerClock
|
||||
{
|
||||
public:
|
||||
static ServerClock &getInstance();
|
||||
|
||||
~ServerClock();
|
||||
const unsigned long getGameTimeSeconds () const;
|
||||
const unsigned long getServerFrame() const;
|
||||
const unsigned long getSubtractInterval() const;
|
||||
void incrementServerFrame();
|
||||
void setSubtractInterval(const unsigned long newSubtractInterval);
|
||||
void setGameTimeSeconds (unsigned long newGameTime);
|
||||
bool isSet () const;
|
||||
std::string getDebugPrintableTimeframe (const unsigned long timeInSeconds);
|
||||
|
||||
static const unsigned long cms_endOfTime;
|
||||
|
||||
protected:
|
||||
ServerClock();
|
||||
|
||||
private:
|
||||
unsigned long serverFrame;
|
||||
unsigned long subtractInterval;
|
||||
mutable time_t lastTime;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline const unsigned long ServerClock::getServerFrame() const
|
||||
{
|
||||
return serverFrame;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline const unsigned long ServerClock::getSubtractInterval() const
|
||||
{
|
||||
return subtractInterval;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool ServerClock::isSet() const
|
||||
{
|
||||
return subtractInterval!=0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,297 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ServerConnection.cpp
|
||||
// copyright 2000 Verant Interactive
|
||||
// Author: Justin Randall
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/ServerConnection.h"
|
||||
|
||||
#include "Archive/ByteStream.h"
|
||||
#include "serverNetworkMessages/CentralGameServerMessages.h"
|
||||
#include "serverNetworkMessages/GameGameServerMessages.h"
|
||||
#include "serverNetworkMessages/ReloadDatatableMessage.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include "sharedNetworkMessages/GameNetworkMessage.h"
|
||||
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
|
||||
#include "sharedFoundation/NetworkIdArchive.h"
|
||||
#include "sharedFoundation/Crc.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "SystemAssignedProcessId.h"
|
||||
#include "unicodeArchive/UnicodeArchive.h"
|
||||
#include <algorithm>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace ServerConnectionNamespace
|
||||
{
|
||||
std::vector<unsigned long int> s_forwardableMessages;
|
||||
}
|
||||
using namespace ServerConnectionNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void ServerConnection::install() // static
|
||||
{
|
||||
s_forwardableMessages.push_back(Crc::calculate("AddGameServer")); // startup
|
||||
s_forwardableMessages.push_back(Crc::calculate("DeltasMessage")); // deltas
|
||||
s_forwardableMessages.push_back(Crc::calculate("SynchronizeScriptVarDeltasMessage"));// deltas
|
||||
s_forwardableMessages.push_back(Crc::calculate("CreateObjectByCrcMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("UpdateObjectPositionMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("BaselinesMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("SynchronizeScriptVarsMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("setDecayTime")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("AiCreatureStateMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("AiMovementMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("EndBaselinesMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("SlowDownEffectMessage")); // baselines
|
||||
s_forwardableMessages.push_back(Crc::calculate("AuthTransferClientMessage")); // auth transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("SetAuthoritativeMessage")); // auth transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("CreateSyncUiMessage")); // auth transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("PageChangeAuthority")); // auth transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("AuthTransferConfirmMessage")); // auth transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("PlayedTimeAccumMessage")); // auth transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("UnloadObjectMessage")); // container transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("UpdateContainmentMessage")); // container transfer
|
||||
s_forwardableMessages.push_back(Crc::calculate("ObjControllerMessage")); // controller messages
|
||||
s_forwardableMessages.push_back(Crc::calculate("TeleportMessage")); // teleport
|
||||
s_forwardableMessages.push_back(Crc::calculate("PlayerSanityCheck")); // player sanity checker
|
||||
s_forwardableMessages.push_back(Crc::calculate("PlayerSanityCheckProxy")); // player sanity checker
|
||||
s_forwardableMessages.push_back(Crc::calculate("PlayerSanityCheckSuccess")); // player sanity checker
|
||||
s_forwardableMessages.push_back(Crc::calculate("PlayerSanityCheckProxyFail")); // player sanity checker
|
||||
s_forwardableMessages.push_back(Crc::calculate("UnloadPersistedCharacter")); // player sanity checker
|
||||
s_forwardableMessages.push_back(Crc::calculate("AddResourceTypeMessage")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("AddImportedResourceType")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("UniverseCompleteMessage")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("SetTheaterMessage")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("ClearTheaterMessage")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("ManualDepleteResourceMessage")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("AddAttribModName")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("AddAttribModNamesList")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("CharacterNamesMessage")); // universe data
|
||||
s_forwardableMessages.push_back(Crc::calculate("MessageToMessage")); // messageTos
|
||||
s_forwardableMessages.push_back(Crc::calculate("WhoHasMessage")); // messageTos
|
||||
s_forwardableMessages.push_back(Crc::calculate("ObjectNotOnServerMessage")); // messageTos
|
||||
s_forwardableMessages.push_back(Crc::calculate("ObjectOnServerMessage")); // messageTos
|
||||
s_forwardableMessages.push_back(Crc::calculate("EnableNewJediTrackingMessage")); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate("EnablePlayerSanityCheckerMessage")); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate("ReloadAdminTableMessage")); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate("ReloadCommandTableMessage")); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate(ReloadDatatableMessage::ms_messageName)); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate("ReloadScriptMessage")); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate("ReloadTemplateMessage")); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate("SetOverrideAccountAgeMessage")); // console commands
|
||||
s_forwardableMessages.push_back(Crc::calculate("ClaimRewardsReplyMessage")); // veteran reward system
|
||||
s_forwardableMessages.push_back(Crc::calculate("UnloadProxyMessage")); // object load
|
||||
s_forwardableMessages.push_back(Crc::calculate("CSRSLReq")); // city (ClusterStartupResidenceStructureListRequest)
|
||||
s_forwardableMessages.push_back(Crc::calculate("CSRSLRsp")); // city (ClusterStartupResidenceStructureListResponse)
|
||||
|
||||
std::sort(s_forwardableMessages.begin(), s_forwardableMessages.end());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const unsigned long ServerConnection::makeProcessId() // static
|
||||
{
|
||||
static unsigned long pid = 0;
|
||||
return ++pid;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ServerConnection::isMessageForwardable(unsigned long int type) // static
|
||||
{
|
||||
return std::binary_search(s_forwardableMessages.begin(), s_forwardableMessages.end(), type);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ServerConnection::MessageConnectionCallback::MessageConnectionCallback(const char * const messageName) :
|
||||
MessageDispatch::MessageBase(messageName)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ServerConnection::MessageConnectionCallback::~MessageConnectionCallback()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ServerConnection::MessageConnectionOverflowing::MessageConnectionOverflowing(const unsigned int newBytesPending) :
|
||||
MessageDispatch::MessageBase("ConnectionOverflowing"),
|
||||
bytesPending(newBytesPending)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ServerConnection::MessageConnectionOverflowing::~MessageConnectionOverflowing()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const unsigned int ServerConnection::MessageConnectionOverflowing::getBytesPending() const
|
||||
{
|
||||
return bytesPending;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ServerConnection::ServerConnection(const std::string & a, const unsigned short p, const NetworkSetupData & setup) :
|
||||
Connection(a, p, setup),
|
||||
MessageDispatch::Emitter(),
|
||||
processId(0),
|
||||
osProcessId(0)
|
||||
{
|
||||
char desc[1024] = {"\0"};
|
||||
snprintf(desc, sizeof(desc), "%s:%d", Os::getProgramName(), Os::getProcessId());
|
||||
GenericValueTypeMessage<std::string> d("DescribeConnection", desc);
|
||||
send(d, true);
|
||||
SystemAssignedProcessId id(Os::getProcessId());
|
||||
send(id, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ServerConnection::ServerConnection(UdpConnectionMT * u, TcpClient * t) :
|
||||
Connection(u, t),
|
||||
MessageDispatch::Emitter(),
|
||||
processId(0),
|
||||
osProcessId(0)
|
||||
{
|
||||
char desc[1024] = {"\0"};
|
||||
snprintf(desc, sizeof(desc), "%s:%d", Os::getProgramName(), Os::getProcessId());
|
||||
GenericValueTypeMessage<std::string> d("DescribeConnection", desc);
|
||||
send(d, true);
|
||||
SystemAssignedProcessId id(Os::getProcessId());
|
||||
send(id, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ServerConnection::~ServerConnection()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::onConnectionClosed()
|
||||
{
|
||||
static MessageConnectionCallback m("ConnectionClosed");
|
||||
emitMessage(m);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::onConnectionOpened()
|
||||
{
|
||||
processId = makeProcessId();
|
||||
static MessageConnectionCallback m("ConnectionOpened");
|
||||
emitMessage(m);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::onConnectionOverflowing(const unsigned int bytesPending)
|
||||
{
|
||||
// not static -- bytesPending is different each time this is invoked
|
||||
MessageConnectionOverflowing m(bytesPending);
|
||||
emitMessage(m);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::onReceive(const Archive::ByteStream & message)
|
||||
{
|
||||
try
|
||||
{
|
||||
Archive::ReadIterator r = message.begin();
|
||||
GameNetworkMessage m(r);
|
||||
r = message.begin();
|
||||
if(m.isType("CentralGameServerSetProcessId"))
|
||||
{
|
||||
CentralGameServerSetProcessId p(r);
|
||||
r = message.begin();
|
||||
processId = p.getProcessId();
|
||||
}
|
||||
else if(m.isType("GameGameServerConnect"))
|
||||
{
|
||||
GameGameServerConnect p(r);
|
||||
r = message.begin();
|
||||
processId = p.getProcessId();
|
||||
}
|
||||
else if(m.isType("SystemAssignedProcessId"))
|
||||
{
|
||||
SystemAssignedProcessId id(r);
|
||||
osProcessId = id.getId();
|
||||
}
|
||||
else if(m.isType("DescribeConnection"))
|
||||
{
|
||||
GenericValueTypeMessage<std::string> d(r);
|
||||
describeConnection(d.getValue());
|
||||
}
|
||||
|
||||
emitMessage(m);
|
||||
}
|
||||
catch(const Archive::ReadException & readException)
|
||||
{
|
||||
WARNING(true, ("Archive::ReadException : %s\n\tDisconnecting from remote server...", readException.what()));
|
||||
disconnect();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::reportReceive(const Archive::ByteStream & bs)
|
||||
{
|
||||
Connection::reportReceive(bs);
|
||||
static Archive::ReadIterator ri;
|
||||
ri = bs.begin();
|
||||
GameNetworkMessage whatIsIt(ri);
|
||||
NetworkHandler::reportMessage("recv." + whatIsIt.getCmdName(), bs.getSize());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::reportSend(const Archive::ByteStream & bs)
|
||||
{
|
||||
Connection::reportReceive(bs);
|
||||
static Archive::ReadIterator ri;
|
||||
ri = bs.begin();
|
||||
GameNetworkMessage whatIsIt(ri);
|
||||
NetworkHandler::reportMessage("send." + whatIsIt.getCmdName(), bs.getSize());
|
||||
|
||||
m_pendingPackets.push_back(std::make_pair(whatIsIt.getCmdName(), bs.getSize()));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::send(const GameNetworkMessage & message, const bool reliable)
|
||||
{
|
||||
static Archive::ByteStream a;
|
||||
a.clear();
|
||||
message.pack(a);
|
||||
Connection::send(a, reliable);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::onConnectionStalled(const unsigned long stallTimeMs)
|
||||
{
|
||||
LOG("Network", ("Connection to %s, pid %d stalled with %d bytes pending for %d milliseconds", getRemoteAddress().c_str(), getOsProcessId(), getPendingBytes(), stallTimeMs));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ServerConnection::setProcessId(const uint32 newProcessId)
|
||||
{
|
||||
processId = newProcessId;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ServerConnection.h
|
||||
// copyright 2000 Verant Interactive
|
||||
// Author: Justin Randall
|
||||
// ======================================================================
|
||||
|
||||
#ifndef _ServerConnection_H
|
||||
#define _ServerConnection_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedMessageDispatch/Emitter.h"
|
||||
#include "sharedMessageDispatch/Message.h"
|
||||
#include "sharedNetwork/Connection.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class GameNetworkMessage;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ServerConnection: public Connection, public MessageDispatch::Emitter
|
||||
{
|
||||
public:
|
||||
ServerConnection (const std::string & address, const unsigned short port, const NetworkSetupData &);
|
||||
ServerConnection (UdpConnectionMT *, TcpClient * t);
|
||||
virtual ~ServerConnection ();
|
||||
|
||||
static void install ();
|
||||
static const unsigned long makeProcessId ();
|
||||
static bool isMessageForwardable (unsigned long int type);
|
||||
|
||||
const unsigned long getProcessId () const;
|
||||
const unsigned long getOsProcessId () const;
|
||||
virtual void onConnectionClosed ();
|
||||
virtual void onConnectionOpened ();
|
||||
virtual void onConnectionOverflowing (const unsigned int bytesPending);
|
||||
virtual void onConnectionStalled (const unsigned long stallTimeMs);
|
||||
virtual void onReceive (const Archive::ByteStream & message);
|
||||
virtual void reportReceive (const Archive::ByteStream & bs);
|
||||
virtual void reportSend (const Archive::ByteStream & bs);
|
||||
virtual void send (const GameNetworkMessage & message, const bool reliable);
|
||||
virtual void setProcessId (const unsigned long newProcessId);
|
||||
|
||||
public:
|
||||
class MessageConnectionCallback: public MessageDispatch::MessageBase
|
||||
{
|
||||
public:
|
||||
MessageConnectionCallback(const char * const messageName);
|
||||
~MessageConnectionCallback();
|
||||
};
|
||||
|
||||
class MessageConnectionOverflowing : public MessageDispatch::MessageBase
|
||||
{
|
||||
public:
|
||||
MessageConnectionOverflowing(const unsigned int bytesPending);
|
||||
~MessageConnectionOverflowing();
|
||||
|
||||
const unsigned int getBytesPending() const;
|
||||
private:
|
||||
unsigned int bytesPending;
|
||||
};
|
||||
|
||||
private:
|
||||
ServerConnection(const ServerConnection&); //disable
|
||||
ServerConnection &operator=(const ServerConnection&); //disable
|
||||
|
||||
private:
|
||||
unsigned long processId;
|
||||
unsigned long osProcessId; // remote's operating system assigned PID
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline const unsigned long ServerConnection::getProcessId(void) const
|
||||
{
|
||||
return processId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
inline const unsigned long ServerConnection::getOsProcessId() const
|
||||
{
|
||||
return osProcessId;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // _ServerConnection_H
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef _SERVER_SERVICE_HANDLER_H
|
||||
#define _SERVER_SERVICE_HANDLER_H
|
||||
|
||||
#include "Network/ConnectionHandler.h"
|
||||
|
||||
#include <list>
|
||||
#include "ServiceHandler.h"
|
||||
|
||||
class ServerServiceHandler :
|
||||
public ServiceHandler
|
||||
{
|
||||
public:
|
||||
virtual ~ServerServiceHandler();
|
||||
virtual void onConnectionClose(NetConnection * closingConnection, ConnectionHandler * connectionHandler, uint32 causeCode);
|
||||
protected:
|
||||
std::list<ConnectionHandler *> _connections;
|
||||
};
|
||||
|
||||
inline ServerServiceHandler::~ServerServiceHandler()
|
||||
{
|
||||
std::list<ConnectionHandler *>::iterator i;
|
||||
ConnectionHandler * c;
|
||||
|
||||
for(i = _connections.begin(); i != _connections.end(); ++i)
|
||||
{
|
||||
c = *i;
|
||||
delete c;
|
||||
}
|
||||
_connections.clear();
|
||||
}
|
||||
|
||||
inline void ServerServiceHandler::onConnectionClose(NetConnection * closingConnection, ConnectionHandler * connectionHandler, uint32 causeCode)
|
||||
{
|
||||
_connections.remove(connectionHandler);
|
||||
delete connectionHandler;
|
||||
}
|
||||
|
||||
#endif _SERVER_SERVICE_HANDLER_H
|
||||
@@ -0,0 +1,25 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// SetupServerUtility.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "serverUtility/SetupServerUtility.h"
|
||||
|
||||
#include "serverUtility/ChatLogManager.h"
|
||||
#include "serverUtility/ConfigServerUtility.h"
|
||||
#include "serverUtility/ServerConnection.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void SetupServerUtility::install()
|
||||
{
|
||||
ConfigServerUtility::install();
|
||||
ChatLogManager::install();
|
||||
ServerConnection::install();
|
||||
}
|
||||
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,27 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// SetupServerUtility.h
|
||||
// copyright (c) 2004 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_SetupServerUtility_H
|
||||
#define INCLUDED_SetupServerUtility_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class SetupServerUtility
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
|
||||
private:
|
||||
SetupServerUtility();
|
||||
SetupServerUtility(const SetupServerUtility &);
|
||||
SetupServerUtility &operator =(const SetupServerUtility &);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
// SystemAssignedProcessId.cpp
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
#include "SystemAssignedProcessId.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
SystemAssignedProcessId::SystemAssignedProcessId(const unsigned long id) :
|
||||
GameNetworkMessage("SystemAssignedProcessId"),
|
||||
m_id(id)
|
||||
{
|
||||
addVariable(m_id);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
SystemAssignedProcessId::SystemAssignedProcessId(Archive::ReadIterator & source) :
|
||||
GameNetworkMessage("SystemAssignedProcessId"),
|
||||
m_id()
|
||||
{
|
||||
addVariable(m_id);
|
||||
unpack(source);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
SystemAssignedProcessId::~SystemAssignedProcessId()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const unsigned long SystemAssignedProcessId::getId() const
|
||||
{
|
||||
return m_id.get();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// SystemAssignedProcessId.h
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_SystemAssignedProcessId_H
|
||||
#define _INCLUDED_SystemAssignedProcessId_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "sharedNetworkMessages/GameNetworkMessage.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class SystemAssignedProcessId : public GameNetworkMessage
|
||||
{
|
||||
public:
|
||||
explicit SystemAssignedProcessId(const unsigned long id);
|
||||
explicit SystemAssignedProcessId(Archive::ReadIterator & source);
|
||||
~SystemAssignedProcessId();
|
||||
|
||||
const unsigned long getId () const;
|
||||
|
||||
private:
|
||||
SystemAssignedProcessId & operator = (const SystemAssignedProcessId & rhs);
|
||||
SystemAssignedProcessId(const SystemAssignedProcessId & source);
|
||||
|
||||
Archive::AutoVariable<unsigned long> m_id;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_SystemAssignedProcessId_H
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#include "serverUtility/FirstServerUtility.h"
|
||||
Reference in New Issue
Block a user