mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 05:07:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "V8Tree/Service.h"
|
||||
#include "V8Tree/Instance.h"
|
||||
#include "Player.h"
|
||||
|
||||
namespace RBX {
|
||||
namespace Network {
|
||||
|
||||
class CustomChatFilter;
|
||||
|
||||
extern const char *const sChatFilter;
|
||||
class ChatFilter
|
||||
: public DescribedNonCreatable<ChatFilter, Instance, sChatFilter, Reflection::ClassDescriptor::INTERNAL_LOCAL>
|
||||
, public Service
|
||||
{
|
||||
public:
|
||||
struct Result {
|
||||
std::string whitelistFilteredMessage;
|
||||
std::string blacklistFilteredMessage;
|
||||
};
|
||||
typedef boost::function<void(const Result&)> FilteredChatMessageCallback;
|
||||
|
||||
ChatFilter() {}
|
||||
|
||||
bool filterMessageBase(shared_ptr<Player> sourcePlayer, shared_ptr<Instance> receiver,
|
||||
const std::string& message, const FilteredChatMessageCallback callback);
|
||||
|
||||
virtual void filterMessage(shared_ptr<Player> sourcePlayer, shared_ptr<Instance> receiver,
|
||||
const std::string& message, const FilteredChatMessageCallback callback) = 0;
|
||||
};
|
||||
}}
|
||||
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include "Util/Math.h"
|
||||
|
||||
namespace RBX
|
||||
{
|
||||
class CompactCFrame
|
||||
{
|
||||
Vector3 rotationaxis;
|
||||
float rotationangle; // angle is always positive.
|
||||
public:
|
||||
Vector3 translation;
|
||||
|
||||
CompactCFrame()
|
||||
: rotationangle(0)
|
||||
{}
|
||||
CompactCFrame(const CoordinateFrame& cframe)
|
||||
: translation(cframe.translation)
|
||||
{
|
||||
cframe.rotation.toAxisAngle(rotationaxis, rotationangle);
|
||||
RBXASSERT(!Math::hasNanOrInf(rotationaxis));
|
||||
RBXASSERT(!Math::isNanInf(rotationangle));
|
||||
}
|
||||
|
||||
CompactCFrame(const Vector3& translation, const Vector3& axisAngle)
|
||||
: translation(translation)
|
||||
, rotationaxis(axisAngle)
|
||||
{
|
||||
rotationangle = rotationaxis.unitize();
|
||||
RBXASSERT(!Math::hasNanOrInf(rotationaxis));
|
||||
RBXASSERT(!Math::isNanInf(rotationangle));
|
||||
}
|
||||
|
||||
CompactCFrame(const Vector3& translation, const Vector3& axis, float angle)
|
||||
: translation(translation)
|
||||
{
|
||||
setAxisAngle(axis, angle);
|
||||
RBXASSERT(!Math::hasNanOrInf(rotationaxis));
|
||||
RBXASSERT(!Math::isNanInf(rotationangle));
|
||||
}
|
||||
|
||||
void setAxisAngle(const Vector3& axis, float angle)
|
||||
{
|
||||
// enforce angle > 0.
|
||||
if(angle >= 0)
|
||||
{
|
||||
rotationaxis = axis;
|
||||
rotationangle = angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotationaxis = axis * -1.0f;
|
||||
rotationangle = -angle;
|
||||
}
|
||||
}
|
||||
|
||||
CoordinateFrame getCFrame() const
|
||||
{
|
||||
CoordinateFrame answer(Matrix3::fromAxisAngleFast(rotationaxis, rotationangle), translation);
|
||||
RBXASSERT(!Math::hasNanOrInf(answer));
|
||||
return answer;
|
||||
}
|
||||
|
||||
Vector3 getAxisAngle() const
|
||||
{
|
||||
return rotationaxis * rotationangle;
|
||||
}
|
||||
|
||||
const Vector3& getAxis() const
|
||||
{
|
||||
return rotationaxis;
|
||||
}
|
||||
|
||||
float getAngle() const
|
||||
{
|
||||
return rotationangle;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#ifndef __CRASH_REPORTER_H
|
||||
#define __CRASH_REPORTER_H
|
||||
|
||||
#include <assert.h>
|
||||
#include "boost/scoped_ptr.hpp"
|
||||
#include "boost/thread.hpp"
|
||||
#include "rbx/CEvent.h"
|
||||
|
||||
|
||||
/// Holds all the parameters to CrashReporter::Start
|
||||
struct CrashReportControls
|
||||
{
|
||||
// Used to generate the dump filename. Required with AOC_EMAIL_WITH_ATTACHMENT or AOC_WRITE_TO_DISK
|
||||
char appName[128];
|
||||
char appVersion[128];
|
||||
|
||||
// Used with AOC_WRITE_TO_DISK . Path to write to. Not the filename, just the path. Empty string means the current directory.
|
||||
char pathToMinidump[260];
|
||||
char crashExtention[64];
|
||||
|
||||
// How much memory to write. MiniDumpNormal is the least but doesn't seem to give correct globals. MiniDumpWithDataSegs gives more.
|
||||
int minidumpType;
|
||||
};
|
||||
|
||||
/// \brief On an unhandled exception, will save a minidump and email it.
|
||||
/// A minidump can be opened in visual studio to give the callstack and local variables at the time of the crash.
|
||||
/// It has the same amount of information as if you crashed while debugging in the relevant mode. So Debug tends to give
|
||||
/// accurate stacks and info while Release does not.
|
||||
///
|
||||
/// Minidumps are only accurate for the code as it was compiled at the date of the release. So you should label releases in source control
|
||||
/// and put that label number in the 'appVersion' field.
|
||||
|
||||
void fixExceptionsThroughKernel();
|
||||
|
||||
class CrashReporter
|
||||
{
|
||||
private:
|
||||
LONG threadResult;
|
||||
struct _EXCEPTION_POINTERS *exceptionInfo;
|
||||
RBX::CEvent reportCrashEvent;
|
||||
boost::scoped_ptr<boost::thread> watcherThread;
|
||||
bool hangReportingEnabled;
|
||||
bool isAlive;
|
||||
LONG deadlockCounter;
|
||||
bool destructing;
|
||||
bool immediateUploadEnabled;
|
||||
|
||||
void LaunchUploadProcess();
|
||||
|
||||
LONG ProcessExceptionHelper(struct _EXCEPTION_POINTERS *ExceptionInfo, bool writeFullDmp, bool noMsg, char* dumpFilepath);
|
||||
|
||||
protected:
|
||||
bool silentCrashReporting;
|
||||
virtual void logEvent(const char* msg) {};
|
||||
public:
|
||||
static CrashReporter* singleton;
|
||||
CrashReportControls controls;
|
||||
CrashReporter();
|
||||
~CrashReporter();
|
||||
void Start();
|
||||
void WatcherThreadFunc();
|
||||
virtual LONG ProcessException(struct _EXCEPTION_POINTERS *ExceptionInfo, bool noMsg);
|
||||
LONG ProcessExceptionInThead(struct _EXCEPTION_POINTERS *ExceptionInfo);
|
||||
void TheadFunc(struct _EXCEPTION_POINTERS *ExceptionInfo);
|
||||
void DisableHangReporting();
|
||||
void EnableImmediateUpload(bool enabled);
|
||||
|
||||
// call every second or so from FG thread to signal responsive app.
|
||||
// must call at least once for hang reporting to be enabled.
|
||||
void NotifyAlive();
|
||||
|
||||
HRESULT GenerateDmpFileName(__out_ecount(cchdumpFilepath) char* dumpFilepath, int cchdumpFilepath, bool fastLog = false, bool fullDmp = false);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "boost/shared_ptr.hpp"
|
||||
#include "boost/thread.hpp"
|
||||
|
||||
namespace Crisp {
|
||||
namespace RMF3 {
|
||||
typedef std::map<std::string, std::string> Data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace RBX {
|
||||
// This very closely mirrors Crisp::RMF3::Response, except we expose the fields directly
|
||||
// and remove the async-specific bits.
|
||||
struct CrispResponse {
|
||||
const std::string id;
|
||||
const int result;
|
||||
const std::string originalContent;
|
||||
const std::string filteredContent;
|
||||
const int errorCode;
|
||||
const std::string errorDescription;
|
||||
|
||||
CrispResponse(
|
||||
const std::string &id_,
|
||||
int result_,
|
||||
const std::string &originalContent_,
|
||||
const std::string &filteredContent_,
|
||||
int errorCode_,
|
||||
const std::string &errorDescription_) :
|
||||
id(id_), result(result_),
|
||||
originalContent(originalContent_), filteredContent(filteredContent_), errorCode(errorCode_),
|
||||
errorDescription(errorDescription_)
|
||||
{}
|
||||
|
||||
inline bool succeeded() const
|
||||
{
|
||||
return 0 == errorCode;
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<const CrispResponse> CrispResponsePtr;
|
||||
|
||||
// An interface of Crisp::RMF3 services. The intention is for subclasses
|
||||
// to implement the behavior so that not all projects need the crisprmf3.dll.
|
||||
class CrispProxy {
|
||||
public:
|
||||
typedef boost::function<void (CrispResponsePtr)> ResponseHandler;
|
||||
|
||||
virtual boost::thread checkContent(
|
||||
const std::string& id,
|
||||
const std::string& sender,
|
||||
const std::string& receiver,
|
||||
const std::string& content,
|
||||
const Crisp::RMF3::Data* pData,
|
||||
const std::string& policy,
|
||||
ResponseHandler &callback) const = 0;
|
||||
|
||||
virtual boost::thread sendEvent(
|
||||
const std::string& id,
|
||||
const std::string& sender,
|
||||
const std::string& receiver,
|
||||
const std::string& event,
|
||||
const Crisp::RMF3::Data *pData,
|
||||
ResponseHandler &callback) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "reflection/Type.h"
|
||||
#include "reflection/Property.h"
|
||||
#include "rbx/signal.h"
|
||||
#include "security/SecurityContext.h"
|
||||
#include "util/Analytics.h"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
class path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace RBX {
|
||||
|
||||
class DataModel;
|
||||
class Instance;
|
||||
class GamePerfMonitor;
|
||||
class ProtectedString;
|
||||
|
||||
namespace Network
|
||||
{
|
||||
class Replicator;
|
||||
}
|
||||
|
||||
class GameConfigurer
|
||||
{
|
||||
public:
|
||||
GameConfigurer() {};
|
||||
virtual ~GameConfigurer() {}
|
||||
|
||||
protected:
|
||||
DataModel* dataModel;
|
||||
boost::shared_ptr<const Reflection::ValueTable> parameters;
|
||||
|
||||
void parseArgs(const std::string& args);
|
||||
int getParamInt(const std::string& key);
|
||||
std::string getParamString(const std::string& key);
|
||||
bool getParamBool(const std::string& key);
|
||||
void registerPlay(const std::string& key, int userId, int placeId);
|
||||
|
||||
void setupUrls();
|
||||
|
||||
public:
|
||||
|
||||
virtual void configure(RBX::Security::Identities identity, DataModel* dm, const std::string& args, int launchMode = -1, const char* vrDevice = 0) = 0;
|
||||
};
|
||||
|
||||
class PlayerConfigurer : public GameConfigurer
|
||||
{
|
||||
bool testing;
|
||||
bool logAnalytics;
|
||||
bool isTouchDevice;
|
||||
bool connectResolved;
|
||||
bool connectionFailed;
|
||||
bool loadResolved;
|
||||
bool joinResolved;
|
||||
bool playResolved;
|
||||
G3D::RealTime startTime;
|
||||
G3D::RealTime playStartTime;
|
||||
bool waitingForCharacter;
|
||||
int launchMode;
|
||||
|
||||
RBX::Analytics::InfluxDb::Points analyticsPoints;
|
||||
boost::shared_ptr<GamePerfMonitor> gamePerfMonitor;
|
||||
|
||||
rbx::signals::scoped_connection playerChangedConnection;
|
||||
|
||||
std::vector<rbx::signals::connection> connections;
|
||||
|
||||
void ifSeleniumThenSetCookie(const std::string& key, const std::string& value);
|
||||
void showErrorWindow(const std::string& message, const std::string& errorType, const std::string& errorCategory);
|
||||
|
||||
void reportError(const std::string& error, const std::string& msg);
|
||||
void reportCounter(const std::string& counterNamesCSV, bool blocking);
|
||||
void reportStats(const std::string& category, float value);
|
||||
void reportDuration(const std::string& category, const std::string& result, double duration, bool blocking);
|
||||
|
||||
void requestCharacter(boost::shared_ptr<Network::Replicator> replicator, boost::shared_ptr<bool> isWaiting);
|
||||
|
||||
void onGameClose();
|
||||
void onDisconnection(const std::string& peer, bool lostConnection);
|
||||
void onConnectionAccepted(std::string url, boost::shared_ptr<Instance> replicator);
|
||||
void onConnectionFailed(const std::string& remoteAddress, int errorCode, const std::string& errorMsg);
|
||||
void onConnectionRejected();
|
||||
void onReceivedGlobals();
|
||||
void onGameLoaded(boost::shared_ptr<bool> isWaiting);
|
||||
void onPlayerIdled(double time);
|
||||
void onPlayerChanged(const Reflection::PropertyDescriptor* propertyDescriptor);
|
||||
|
||||
void setMessage(const std::string& msg);
|
||||
|
||||
public:
|
||||
PlayerConfigurer();
|
||||
~PlayerConfigurer();
|
||||
|
||||
/*override*/ void configure(RBX::Security::Identities identity, DataModel* dm, const std::string& args, int launchMode = -1, const char* vrDevice = 0);
|
||||
|
||||
};
|
||||
|
||||
class StudioConfigurer : public GameConfigurer
|
||||
{
|
||||
private:
|
||||
bool findModulesAndLoad(const std::string& baseModulePath, const boost::filesystem::path& dir_path, boost::unordered_map<std::string, ProtectedString>& coreModules);
|
||||
void loadCoreModules();
|
||||
public:
|
||||
StudioConfigurer() {}
|
||||
~StudioConfigurer() {}
|
||||
|
||||
std::string starterScript;
|
||||
/*override*/ void configure(RBX::Security::Identities identity, DataModel* dm, const std::string& args, int launchMode = -1, const char* vrDevice = 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "boost/thread/mutex.hpp"
|
||||
|
||||
namespace RBX { namespace Network {
|
||||
class Replicator;
|
||||
}
|
||||
}
|
||||
|
||||
namespace RBX {
|
||||
namespace Security{
|
||||
|
||||
struct NetPmcChallenge
|
||||
{
|
||||
// these will be encrypted on the game client
|
||||
uint32_t base;
|
||||
uint32_t size;
|
||||
uint32_t seed;
|
||||
// This will be encrypted in a different way.
|
||||
uint64_t result;
|
||||
|
||||
NetPmcChallenge& operator^=(const NetPmcChallenge& rhs)
|
||||
{
|
||||
this->base ^= rhs.base;
|
||||
this->size ^= rhs.size;
|
||||
this->seed ^= rhs.seed;
|
||||
this->result ^= rhs.result;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
const size_t kNumChallenges = 128;
|
||||
extern const volatile NetPmcChallenge kChallenges[kNumChallenges];
|
||||
|
||||
#ifndef RBX_STUDIO_BUILD
|
||||
|
||||
uint32_t netPmcHashCheck(const NetPmcChallenge& challenge);
|
||||
|
||||
#endif
|
||||
|
||||
void salsa20(uint8_t *message, uint64_t mlen, uint8_t key[32], uint64_t nonce);
|
||||
// This will appear in the release patcher and in RCC, but not in studio or the final client.
|
||||
__forceinline std::vector<NetPmcChallenge> generateNetPmcKeys()
|
||||
{
|
||||
std::vector<NetPmcChallenge> keys;
|
||||
keys.resize(kNumChallenges);
|
||||
uint8_t key[32];
|
||||
for (size_t i = 0; i < 32; ++i)
|
||||
{
|
||||
key[i] = (i+1)*(i^0x55);
|
||||
}
|
||||
RBX::Security::salsa20(reinterpret_cast<uint8_t*>(keys.data()), sizeof(NetPmcChallenge)*kNumChallenges, key, 2015);
|
||||
return keys;
|
||||
}
|
||||
|
||||
#ifdef RBX_RCC_SECURITY
|
||||
extern std::vector<NetPmcChallenge> netPmcKeys;
|
||||
|
||||
class NetPmcServer
|
||||
{
|
||||
std::vector<uint8_t> challenges;
|
||||
uint8_t challengeIdx;
|
||||
|
||||
std::vector<uint8_t> challengesInFlight;
|
||||
boost::mutex flightMutex;
|
||||
|
||||
bool isGameCreator;
|
||||
bool gameHasManyPlayers;
|
||||
bool gameHasManyParts;
|
||||
bool userHasActivity;
|
||||
|
||||
size_t challengesSent;
|
||||
size_t challengesRecv;
|
||||
|
||||
public:
|
||||
NetPmcServer();
|
||||
|
||||
// the intent it to make it much harder to detect this mechanism by making it
|
||||
// only work in places that are actually games.
|
||||
bool canSendChallenge(const RBX::Network::Replicator* rep); /*non-const*/
|
||||
|
||||
bool tooManyPending() const;
|
||||
|
||||
uint8_t getRandomChallenge();
|
||||
|
||||
bool sendChallenge(uint8_t idx);
|
||||
|
||||
bool removeFromList(uint8_t idx);
|
||||
|
||||
bool checkResult(uint8_t idx, uint32_t response, uint64_t correct) const;
|
||||
|
||||
unsigned int generateDebugInfo(const RBX::Network::Replicator* rep, uint32_t& sent, uint32_t& recv, uint32_t& pending) const;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
#include "V8Tree/Service.h"
|
||||
#include "rbx/signal.h"
|
||||
#include "Util/StreamRegion.h"
|
||||
|
||||
#include "voxel/CellChangeListener.h"
|
||||
#include "voxel2/GridListener.h"
|
||||
|
||||
namespace RakNet {
|
||||
class BitStream;
|
||||
}
|
||||
|
||||
namespace RBX {
|
||||
|
||||
class MegaClusterInstance;
|
||||
|
||||
namespace Network {
|
||||
// This class stores the final raknet bit stream of each cluster chunk.
|
||||
// Cache operations are guarded by a shared mutex that uses readers-writer lock,
|
||||
// this allows multiple send jobs to fetch from cache concurrently, but only one can update at any given time
|
||||
extern const char* const sClusterPacketCacheBase;
|
||||
|
||||
template <class Key>
|
||||
class ClusterPacketCacheBase
|
||||
: public Voxel::CellChangeListener
|
||||
, public Voxel2::GridListener
|
||||
{
|
||||
protected:
|
||||
struct CachedBitStream
|
||||
{
|
||||
bool dirty;
|
||||
boost::shared_ptr<RakNet::BitStream> bitStream;
|
||||
|
||||
CachedBitStream() : dirty(true) {}
|
||||
};
|
||||
|
||||
typedef boost::unordered_map<Key, CachedBitStream> StreamCacheList;
|
||||
StreamCacheList streamCache;
|
||||
|
||||
boost::shared_mutex sharedMutex;
|
||||
boost::shared_ptr<MegaClusterInstance> clusterInstance;
|
||||
|
||||
public:
|
||||
ClusterPacketCacheBase();
|
||||
virtual ~ClusterPacketCacheBase() {};
|
||||
|
||||
// Search for cached bitstream by index. This function uses a shared locked to allow multiple reads at same time.
|
||||
// Returns true if fetched successfully.
|
||||
bool fetchIfUpToDate(const Key ®ionId, RakNet::BitStream& outBitStream);
|
||||
|
||||
// Copy all data from bitStream to cache. This function upgrades the shard mutex into an unique lock that blocks all other
|
||||
// read and write operations.
|
||||
bool update(const Key ®ionId, RakNet::BitStream& bitStream, unsigned int numBits);
|
||||
|
||||
unsigned int getCachedBitStreamBytesUsed(const Key ®ionId);
|
||||
|
||||
void setupListener(MegaClusterInstance* megaClusterInstance);
|
||||
|
||||
protected:
|
||||
void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
|
||||
};
|
||||
|
||||
extern const char* const sClusterPacketCache;
|
||||
class ClusterPacketCache
|
||||
: public ClusterPacketCacheBase<SpatialRegion::Id>
|
||||
, public DescribedNonCreatable<ClusterPacketCache, Instance, sClusterPacketCache>
|
||||
, public Service
|
||||
{
|
||||
public:
|
||||
ClusterPacketCache()
|
||||
{
|
||||
setName(sClusterPacketCache);
|
||||
};
|
||||
~ClusterPacketCache() {};
|
||||
|
||||
void terrainCellChanged(const Voxel::CellChangeInfo& cell) override;
|
||||
void onTerrainRegionChanged(const Voxel2::Region& region) override;
|
||||
};
|
||||
|
||||
extern const char* const sOneQuarterClusterPacketCache;
|
||||
class OneQuarterClusterPacketCache
|
||||
: public ClusterPacketCacheBase<StreamRegion::Id>
|
||||
, public DescribedNonCreatable<OneQuarterClusterPacketCache, Instance, sOneQuarterClusterPacketCache>
|
||||
, public Service
|
||||
{
|
||||
public:
|
||||
OneQuarterClusterPacketCache()
|
||||
{
|
||||
setName(sOneQuarterClusterPacketCache);
|
||||
};
|
||||
~OneQuarterClusterPacketCache() {};
|
||||
|
||||
void terrainCellChanged(const Voxel::CellChangeInfo& cell) override;
|
||||
void onTerrainRegionChanged(const Voxel2::Region& region) override;
|
||||
};
|
||||
}}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Util/SystemAddress.h"
|
||||
#include "Util/Color.h"
|
||||
|
||||
namespace RBX {
|
||||
namespace Network {
|
||||
|
||||
class NetworkOwner
|
||||
{
|
||||
public:
|
||||
static const RBX::SystemAddress Server() {
|
||||
static RBX::SystemAddress s(1, 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
// created on server, have not be properly assigned via network owner job
|
||||
static const RBX::SystemAddress ServerUnassigned() {
|
||||
static RBX::SystemAddress s(1, 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
// default
|
||||
static const RBX::SystemAddress Unassigned() {
|
||||
static RBX::SystemAddress s;
|
||||
RBXASSERT(s == SystemAddress());
|
||||
RBXASSERT(s != NetworkOwner::Server());
|
||||
RBXASSERT(s != NetworkOwner::ServerUnassigned());
|
||||
RBXASSERT(s != NetworkOwner::AssignedOther());
|
||||
return s;
|
||||
}
|
||||
|
||||
// generic value used on client indicating assigned to other clients or server (i.e. not self)
|
||||
static const RBX::SystemAddress AssignedOther() {
|
||||
static RBX::SystemAddress s(0, 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool isClient(const RBX::SystemAddress& address) {
|
||||
return ( (address != Server())
|
||||
&& (address != Unassigned())
|
||||
&& (address != ServerUnassigned()));
|
||||
}
|
||||
|
||||
static bool isServer(const RBX::SystemAddress& address) {
|
||||
return address == Server() || address == ServerUnassigned();
|
||||
}
|
||||
|
||||
static Color3 colorFromAddress(const RBX::SystemAddress& systemAddress) {
|
||||
if (systemAddress == Server()) {
|
||||
return Color3::white();
|
||||
}
|
||||
else if (systemAddress == Unassigned() || systemAddress == ServerUnassigned()) {
|
||||
return Color3::black();
|
||||
}
|
||||
else if (systemAddress == AssignedOther())
|
||||
return Color3::gray();
|
||||
else {
|
||||
unsigned int address = systemAddress.getAddress();
|
||||
unsigned int port = systemAddress.getPort();
|
||||
address += port;
|
||||
return RBX::Color::colorFromInt(address);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}} // namespace
|
||||
@@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "V8Tree/Service.h"
|
||||
#include "v8datamodel/partinstance.h"
|
||||
#include "rbx/signal.h"
|
||||
#include <boost/unordered/unordered_map.hpp>
|
||||
|
||||
namespace RakNet {
|
||||
class BitStream;
|
||||
}
|
||||
|
||||
namespace RBX {
|
||||
namespace Network {
|
||||
|
||||
extern const char* const sPhysicsPacketCache;
|
||||
class PhysicsPacketCache
|
||||
: public DescribedNonCreatable<PhysicsPacketCache, Instance, sPhysicsPacketCache>
|
||||
, public Service
|
||||
{
|
||||
typedef DescribedNonCreatable<PhysicsPacketCache, Instance, sPhysicsPacketCache> Super;
|
||||
|
||||
public:
|
||||
class CachedBitStream
|
||||
{
|
||||
public:
|
||||
int lastStepId;
|
||||
int dataBitStartOffset;
|
||||
int totalNumBits;
|
||||
boost::shared_ptr<RakNet::BitStream> bitStream;
|
||||
|
||||
CachedBitStream() : lastStepId(0), dataBitStartOffset(0), totalNumBits(0) {}
|
||||
~CachedBitStream() {}
|
||||
};
|
||||
|
||||
private:
|
||||
typedef boost::unordered_map<unsigned char, boost::shared_ptr<CachedBitStream> > InnerMap;
|
||||
typedef boost::unordered_map<const Assembly*, InnerMap> StreamCacheMap;
|
||||
StreamCacheMap streamCache;
|
||||
boost::shared_mutex sharedMutex;
|
||||
|
||||
rbx::signals::scoped_connection addingAssemblyConnection;
|
||||
rbx::signals::scoped_connection removedAssemblyConnection;
|
||||
|
||||
public:
|
||||
PhysicsPacketCache();
|
||||
~PhysicsPacketCache();
|
||||
|
||||
bool fetchIfUpToDate(const Assembly* key, unsigned char index, RakNet::BitStream& outBitStream);
|
||||
|
||||
// copy data from bitStream starting at its read position to numBits
|
||||
bool update(const Assembly* key, unsigned char index, RakNet::BitStream& bitStream, unsigned int startReadBitPos, unsigned int numBits);
|
||||
|
||||
protected:
|
||||
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
|
||||
|
||||
private:
|
||||
void insert(const Assembly* key);
|
||||
void insertChildAssembly(const Assembly* assembly);
|
||||
void remove(const Assembly* key);
|
||||
void removeChildAssembly(const Assembly* assembly);
|
||||
void onAddingAssembly(shared_ptr<Instance> assembly);
|
||||
void onRemovedAssembly(shared_ptr<Instance> assembly);
|
||||
void addPart(PartInstance& part);
|
||||
|
||||
boost::unique_lock<boost::shared_mutex> debugLock(boost::upgrade_lock<boost::shared_mutex>* upgradeLock = NULL);
|
||||
};
|
||||
|
||||
|
||||
extern const char* const sInstancePacketCache;
|
||||
class InstancePacketCache
|
||||
: public DescribedNonCreatable<InstancePacketCache, Instance, sInstancePacketCache>
|
||||
, public Service
|
||||
{
|
||||
typedef DescribedNonCreatable<InstancePacketCache, Instance, sInstancePacketCache> Super;
|
||||
typedef std::list<rbx::signals::connection> ConnectionList;
|
||||
|
||||
class CachedBitStream
|
||||
{
|
||||
public:
|
||||
bool dirty;
|
||||
|
||||
// regular new instance data containing non dictionary properties, and join time data containing all properties (except parent)
|
||||
boost::shared_ptr<RakNet::BitStream> bitStream[2];
|
||||
|
||||
// debug
|
||||
const std::string guidString;
|
||||
|
||||
rbx::signals::scoped_connection propChangedConnection;
|
||||
rbx::signals::scoped_connection ancestorChangedConnection;
|
||||
|
||||
CachedBitStream(const std::string& guid) : dirty(true), guidString(guid) {}
|
||||
~CachedBitStream() {}
|
||||
|
||||
void onPropertyChanged(const RBX::Reflection::PropertyDescriptor* desc) { dirty = true; }
|
||||
};
|
||||
|
||||
typedef boost::unordered_map<const Instance*, boost::shared_ptr<CachedBitStream> > StreamCacheMap;
|
||||
StreamCacheMap streamCache;
|
||||
boost::shared_mutex sharedMutex;
|
||||
|
||||
ConnectionList connections;
|
||||
|
||||
void onAncestorChanged(shared_ptr<Instance> instance, shared_ptr<Instance> newParent);
|
||||
|
||||
public:
|
||||
InstancePacketCache();
|
||||
~InstancePacketCache();
|
||||
|
||||
// not thread safe
|
||||
void insert(const Instance* key);
|
||||
|
||||
// not thread safe
|
||||
void remove(const Instance* key);
|
||||
|
||||
bool fetchIfUpToDate(const Instance* key, RakNet::BitStream& outBitStream, bool isJoinData);
|
||||
|
||||
// copy data from bitStream starting at its read position to numBits
|
||||
bool update(const Instance* key, RakNet::BitStream& bitStream, unsigned int numBits, bool isJoinData);
|
||||
|
||||
protected:
|
||||
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,496 @@
|
||||
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rbx/rbxTime.h"
|
||||
#include "v8tree/instance.h"
|
||||
#include "v8datamodel/team.h"
|
||||
#include "V8Datamodel/FriendService.h"
|
||||
#include "V8DataModel/Camera.h"
|
||||
#include "V8DataModel/StarterPlayerService.h"
|
||||
#include "Util/BrickColor.h"
|
||||
#include "Util/G3DCore.h"
|
||||
#include "Util/HeapValue.h"
|
||||
#include "Util/Rect.h"
|
||||
#include "util/RunningAverage.h"
|
||||
|
||||
// for player mouse
|
||||
#include "V8Datamodel/Mouse.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "v8datamodel/TeleportService.h"
|
||||
|
||||
LOGGROUP(Network)
|
||||
LOGGROUP(Player)
|
||||
|
||||
namespace RakNet {
|
||||
struct SystemAddress;
|
||||
}
|
||||
|
||||
namespace RBX {
|
||||
class Visit;
|
||||
class ModelInstance;
|
||||
class Backpack;
|
||||
class TimerService;
|
||||
class Region2;
|
||||
class DataModelMesh;
|
||||
class Adorn;
|
||||
class Primitive;
|
||||
class PartInstance;
|
||||
class Humanoid;
|
||||
class DataModel;
|
||||
class SpawnLocation;
|
||||
|
||||
namespace Network {
|
||||
class PersistentDataStore;
|
||||
|
||||
extern const char* const sPlayer;
|
||||
|
||||
class Player
|
||||
: public DescribedCreatable<Player, Instance, sPlayer, Reflection::ClassDescriptor::RUNTIME>
|
||||
, public Diagnostics::Countable<Player>
|
||||
{
|
||||
private:
|
||||
typedef DescribedCreatable<Player, Instance, sPlayer, Reflection::ClassDescriptor::RUNTIME> Super;
|
||||
shared_ptr<ModelInstance> character; // The ModelInstance that this player is represented by
|
||||
BrickColor teamColor;
|
||||
bool neutral;
|
||||
int loadAppearanceCounter;
|
||||
int dataComplexityLimit;
|
||||
bool dataReady;
|
||||
weak_ptr<SpawnLocation> respawnLocation;
|
||||
CoordinateFrame cloudEditCameraCFrame;
|
||||
|
||||
bool loadedStarterGear;
|
||||
|
||||
// User Profile data
|
||||
bool superSafeChat;
|
||||
bool under13;
|
||||
int userId;
|
||||
|
||||
// For Group Building
|
||||
bool hasGroupBuildTools;
|
||||
HeapValue<int> personalServerRank;
|
||||
|
||||
rbx::signals::scoped_connection characterDiedConnection;
|
||||
rbx::signals::scoped_connection backendDiedSignalConnection;
|
||||
rbx::signals::scoped_connection spawnLocationChangedConnection;
|
||||
rbx::signals::scoped_connection simulationRadiusChangedConnection;
|
||||
rbx::signals::scoped_connection setShutdownMessageConnection;
|
||||
boost::function<void()> teamStatusChangedCallback;
|
||||
|
||||
// CharacterAppearance is the url of a handler that returns a delimited list of asset ids
|
||||
std::string characterAppearance;
|
||||
bool canLoadCharacterAppearance;
|
||||
|
||||
// Distributed Simulation
|
||||
float simulationRadius;
|
||||
float maxSimulationRadius;
|
||||
|
||||
std::string osPlatform;
|
||||
std::string vrDevice;
|
||||
|
||||
int loadingInstances;
|
||||
bool appearanceDidLoad;
|
||||
bool characterAppearanceLoaded;
|
||||
|
||||
// Only valid on the server!
|
||||
shared_ptr<RakNet::SystemAddress> remoteAddress;
|
||||
|
||||
bool forceEarlySpawnLocationCalculation;
|
||||
bool hasSpawnedAtLeastOnce;
|
||||
std::string teleportSpawnName;
|
||||
bool teleported; // describes whether player is currently in the middle of teleporting out
|
||||
bool teleportedIn; // describes whether player joined current place by teleporting
|
||||
|
||||
std::string gameSessionID;
|
||||
|
||||
struct SpawnData
|
||||
{
|
||||
Vector3 position;
|
||||
int forceFieldDuration;
|
||||
CoordinateFrame cf;
|
||||
|
||||
SpawnData() : position(Vector3::zero()), forceFieldDuration(0) {}
|
||||
SpawnData(Vector3 position, int forceFieldDuration, CoordinateFrame frame)
|
||||
: position(position), forceFieldDuration(forceFieldDuration), cf(frame)
|
||||
{}
|
||||
};
|
||||
|
||||
boost::scoped_ptr<SpawnData> nextSpawnLocation;
|
||||
|
||||
int followUserId;
|
||||
|
||||
// Instance
|
||||
/*override*/ bool askAddChild(const Instance* instance) const {return true;}
|
||||
/*override*/ void verifySetParent(const Instance* instance) const;
|
||||
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
|
||||
|
||||
void onCharacterChangedFrontend();
|
||||
|
||||
void registerLocalPlayerNotIdle();
|
||||
|
||||
void loadInsertPanel(DataModel* dataModel);
|
||||
|
||||
shared_ptr<PersistentDataStore> persistentData;
|
||||
std::list<boost::function<void(bool)> > waitForDataReadyWaiters;
|
||||
void fireWaitForDataReady();
|
||||
static void LoadDataResultHelper(boost::weak_ptr<Player> weakPlayer, shared_ptr<const Reflection::ValueMap> result);
|
||||
void loadDataResult(shared_ptr<const Reflection::ValueMap> result);
|
||||
|
||||
bool autoJumpEnabled;
|
||||
|
||||
public:
|
||||
enum MembershipType
|
||||
{
|
||||
MEMBERSHIP_NONE = 0,
|
||||
MEMBERSHIP_BUILDERS_CLUB = 1,
|
||||
MEMBERSHIP_TURBO_BUILDERS_CLUB = 2,
|
||||
MEMBERSHIP_OUTRAGEOUS_BUILDERS_CLUB = 3
|
||||
};
|
||||
enum ChatMode
|
||||
{
|
||||
CHAT_MODE_MENU = 0,
|
||||
CHAT_MODE_TEXT_AND_MENU = 1
|
||||
};
|
||||
enum ChatFilterType {
|
||||
CHAT_FILTER_WHITELIST,
|
||||
CHAT_FILTER_BLACKLIST
|
||||
};
|
||||
|
||||
// debug timer
|
||||
RBX::Timer<RBX::Time::Fast> appearanceFetchTimer;
|
||||
|
||||
static Reflection::PropDescriptor<Player, int> prop_userId;
|
||||
static Reflection::PropDescriptor<Player, int> prop_userIdDeprecated;
|
||||
static Reflection::PropDescriptor<Player, bool> prop_SuperSafeChat;
|
||||
static Reflection::BoundProp<float> prop_SimulationRadius;
|
||||
static Reflection::BoundProp<float> prop_MaxSimulationRadius;
|
||||
static Reflection::PropDescriptor<Player, float> prop_DeprecatedMaxSimulationRadius;
|
||||
static Reflection::BoundProp<std::string> prop_OsPlatform;
|
||||
static Reflection::BoundProp<std::string> prop_VRDevice;
|
||||
static Reflection::RemoteEventDesc<Player, void(shared_ptr<const Reflection::ValueArray>)> event_cloudEditSelectionChanged;
|
||||
|
||||
rbx::remote_signal<void(std::string, std::string, std::string)> scriptSecurityErrorSignal;
|
||||
rbx::remote_signal<void(std::string,Vector3)> remoteInsertSignal;
|
||||
|
||||
rbx::remote_signal<void()> connectDiedSignalBackend;
|
||||
|
||||
rbx::remote_signal<void(bool,int)> remoteFriendServiceSignal;
|
||||
rbx::remote_signal<void()> killPlayerSignal;
|
||||
rbx::remote_signal<void(float)> simulationRadiusChangedSignal;
|
||||
|
||||
rbx::remote_signal<void(std::string)> statsSignal;
|
||||
rbx::signals::scoped_connection charChildAddedConnection;
|
||||
|
||||
rbx::signal<void(std::string, shared_ptr<Instance>)> chattedSignal;
|
||||
rbx::signal<void(shared_ptr<Instance>)> characterAddedSignal;
|
||||
rbx::remote_signal<void(shared_ptr<Instance>)> CharacterAppearanceLoadedSignal;
|
||||
rbx::signal<void(shared_ptr<Instance>)> characterRemovingSignal;
|
||||
rbx::signal<void(Vector3)> nextSpawnLocationChangedSignal;
|
||||
rbx::signal<void(double)> idledSignal;
|
||||
|
||||
rbx::signal<void(shared_ptr<Instance>, FriendService::FriendStatus)> friendStatusChangedSignal;
|
||||
|
||||
rbx::remote_signal<void(TeleportService::TeleportState, int, std::string)> onTeleportSignal;
|
||||
rbx::remote_signal<void(TeleportService::TeleportState, shared_ptr<const Reflection::ValueTable>, shared_ptr<Instance>)> onTeleportInternalSignal;
|
||||
|
||||
rbx::remote_signal<void(std::string)> setShutdownMessageSignal;
|
||||
rbx::remote_signal<void(shared_ptr<const Reflection::ValueArray>)> cloudEditSelectionChanged;
|
||||
|
||||
Player();
|
||||
~Player();
|
||||
|
||||
void doFirstSpawnLocationCalculation(const ServiceProvider* serviceProvider, const std::string& preferedSpawnName);
|
||||
void reportScriptSecurityError(const std::string& hash, const std::string& error, const std::string& stack);
|
||||
void killPlayer();
|
||||
|
||||
void requestFriendship(shared_ptr<Instance> player);
|
||||
void revokeFriendship(shared_ptr<Instance> player);
|
||||
|
||||
// Keyboard/Mouse input API
|
||||
shared_ptr<Mouse> getMouse() { return mouse; }
|
||||
shared_ptr<Instance> getMouseInstance();
|
||||
|
||||
//Persistent Data API
|
||||
void loadData();
|
||||
void saveData();
|
||||
void saveLeaderboardData();
|
||||
int getDataComplexityLimit() const { return dataComplexityLimit; }
|
||||
void setDataComplexityLimit(int value);
|
||||
int getDataComplexity() const;
|
||||
|
||||
bool getDataReady() const { return dataReady; }
|
||||
|
||||
void waitForDataReady(boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
double loadNumber(std::string key);
|
||||
void saveNumber(std::string key, double value);
|
||||
std::string loadString(std::string key);
|
||||
void saveString(std::string key, std::string value);
|
||||
bool loadBoolean(std::string key);
|
||||
void saveBoolean(std::string key, bool value);
|
||||
shared_ptr<Instance> loadInstance(std::string key);
|
||||
void saveInstance(std::string key, shared_ptr<Instance> value);
|
||||
shared_ptr<const Reflection::ValueArray> loadList(std::string key);
|
||||
void saveList(std::string key, shared_ptr<const Reflection::ValueArray> value);
|
||||
shared_ptr<const RBX::Reflection::ValueMap> loadTable(std::string key);
|
||||
void saveTable(std::string key, shared_ptr<const RBX::Reflection::ValueMap> value);
|
||||
|
||||
/*override*/ void setName(const std::string& value);
|
||||
/*override*/ bool canClientCreate() { return true; }
|
||||
|
||||
ModelInstance* getDangerousCharacter() const {return character.get();}
|
||||
|
||||
boost::shared_ptr<ModelInstance> getSharedCharacter() {return character; }
|
||||
ModelInstance* getCharacter() {return character.get();}
|
||||
const ModelInstance* getConstCharacter() const {return character.get();}
|
||||
void setCharacter(ModelInstance* value);
|
||||
|
||||
const SpawnLocation* getConstRespawnLocation() const {
|
||||
if (shared_ptr<SpawnLocation> shared_respawnLocation = respawnLocation.lock())
|
||||
return shared_respawnLocation.get();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
SpawnLocation* getDangerousRespawnLocation() const {
|
||||
if (shared_ptr<SpawnLocation> shared_respawnLocation = respawnLocation.lock())
|
||||
return shared_respawnLocation.get();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
void setRespawnLocation(SpawnLocation* value);
|
||||
|
||||
bool getCanLoadCharacterAppearance() const { return canLoadCharacterAppearance;}
|
||||
void setCanLoadCharacterAppearance(bool value);
|
||||
|
||||
bool getAutoJumpEnabled() const { return autoJumpEnabled; }
|
||||
void setAutoJumpEnabled(bool value);
|
||||
|
||||
const PartInstance* hasCharacterHead(CoordinateFrame& headPos) const;
|
||||
|
||||
bool getHasGroupBuildTools() const { return hasGroupBuildTools; }
|
||||
void setHasGroupBuildTools(bool value);
|
||||
|
||||
void giveBuildTools();
|
||||
void removeBuildTools();
|
||||
|
||||
void setAppearanceLoaded();
|
||||
|
||||
// Personal Server API
|
||||
void getWebPersonalServerRank(boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void setWebPersonalServerRank(int newRank, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
|
||||
int getPersonalServerRank() const { return (personalServerRank > 255) ? 0 : personalServerRank; } // 255 is max rank allowed by setter.
|
||||
void setPersonalServerRank(int value);
|
||||
|
||||
const Primitive* getConstCharacterRoot() const;
|
||||
|
||||
BrickColor getTeamColor() const {return teamColor;}
|
||||
void setTeamColor(BrickColor value);
|
||||
|
||||
bool getNeutral() const {return neutral;}
|
||||
void setNeutral(bool value);
|
||||
|
||||
std::string getCharacterAppearance() const {return characterAppearance;}
|
||||
void setCharacterAppearance(const std::string& value);
|
||||
|
||||
static void setAppearanceParent(weak_ptr<Player> player, weak_ptr<Instance> instance, bool equipped);
|
||||
|
||||
static void setGearParent(weak_ptr<Player> player, weak_ptr<Instance> instance, bool equipped);
|
||||
|
||||
bool getSuperSafeChat() const;
|
||||
void setSuperSafeChat(bool value);
|
||||
|
||||
float getDeprecatedMaxSimulationRadius() const {return 0.f;}
|
||||
void setDeprecatedMaxSimulationRadius(float val){}
|
||||
|
||||
ChatMode getChatMode() const;
|
||||
|
||||
void setUnder13(bool value);
|
||||
bool getUnder13() {return under13;};
|
||||
|
||||
void setUserId(int value);
|
||||
int getUserID() const {return userId;}
|
||||
|
||||
void setGameSessionID(std::string value);
|
||||
std::string getGameSessionID() { return gameSessionID; }
|
||||
|
||||
bool isGuest() const { return userId < 0; }
|
||||
void setMembershipType(MembershipType value);
|
||||
MembershipType getMembershipType() const {return membershipType;}
|
||||
|
||||
void setCameraMode(RBX::Camera::CameraMode value);
|
||||
RBX::Camera::CameraMode getCameraMode() const {return cameraMode;}
|
||||
|
||||
|
||||
void setNameDisplayDistance(float value);
|
||||
float getNameDisplayDistance() const {return nameDisplayDistance;}
|
||||
|
||||
void setHealthDisplayDistance(float value);
|
||||
float getHealthDisplayDistance() const {return healthDisplayDistance;}
|
||||
|
||||
void setCameraMaxZoomDistance(float _cameraMaxZoomDistance);
|
||||
float getCameraMaxZoomDistance() const {return cameraMaxZoomDistance;}
|
||||
|
||||
void setCameraMinZoomDistance(float _cameraMinZoomDistance);
|
||||
float getCameraMinZoomDistance() const {return cameraMinZoomDistance;}
|
||||
|
||||
void setDevEnableMouseLockOption(bool setting);
|
||||
bool getDevEnableMouseLockOption() const {return enableMouseLockOption;}
|
||||
void setDevTouchCameraMode(StarterPlayerService::DeveloperTouchCameraMovementMode setting);
|
||||
StarterPlayerService::DeveloperTouchCameraMovementMode getDevTouchCameraMode() const {return touchCameraMovementMode;}
|
||||
void setDevComputerCameraMode(StarterPlayerService::DeveloperComputerCameraMovementMode setting);
|
||||
StarterPlayerService::DeveloperComputerCameraMovementMode getDevComputerCameraMode() const {return computerCameraMovementMode;}
|
||||
void setDevCameraOcclusionMode(StarterPlayerService::DeveloperCameraOcclusionMode setting);
|
||||
StarterPlayerService::DeveloperCameraOcclusionMode getDevCameraOcclusionMode() const {return cameraOcclusionMode;}
|
||||
|
||||
void setDevTouchMovementMode(StarterPlayerService::DeveloperTouchMovementMode setting);
|
||||
StarterPlayerService::DeveloperTouchMovementMode getDevTouchMovementMode() const {return touchMovementMode;}
|
||||
void setDevComputerMovementMode(StarterPlayerService::DeveloperComputerMovementMode setting);
|
||||
StarterPlayerService::DeveloperComputerMovementMode getDevComputerMovementMode() const {return computerMovementMode;}
|
||||
|
||||
void setAccountAge(int value);
|
||||
int getAccountAge() const {return accountAge;}
|
||||
|
||||
void updateSimulationRadius(float value);
|
||||
float getSimulationRadius() const {return simulationRadius;}
|
||||
void setSimulationRadius(float value);
|
||||
|
||||
float getMaxSimulationRadius() const {return maxSimulationRadius;}
|
||||
void setMaxSimulationRadius(float value);
|
||||
|
||||
CoordinateFrame getCloudEditCameraCoordinateFrame() const { return cloudEditCameraCFrame; }
|
||||
void setCloudEditCameraCoordinateFrame(const CoordinateFrame& cframe);
|
||||
|
||||
std::string getOsPlatform() const {return osPlatform;}
|
||||
|
||||
void rebuildBackpack(); // Copy the backpack from the StartPack service
|
||||
void rebuildGui(); // Copy the gui from the StarterGui service
|
||||
void rebuildPlayerScripts(); // Copy the LocalScripts from the StarterPlayer/PlayerScripts service
|
||||
|
||||
void createPlayerGui();
|
||||
|
||||
Backpack* getPlayerBackpack();
|
||||
const Backpack* getConstPlayerBackpack() const;
|
||||
|
||||
void luaJumpCharacter();
|
||||
void luaMoveCharacter(Vector2 walkDirection, float maxWalkDelta);
|
||||
|
||||
void move(Vector3 walkVector, bool relativeToCamera);
|
||||
|
||||
float distanceFromCharacter(Vector3 point);
|
||||
|
||||
void luaLoadCharacter(bool inGame);
|
||||
void loadCharacter(bool inGame, std::string preferedSpawnName);
|
||||
|
||||
void removeCharacter();
|
||||
void removeCharacterAppearance();
|
||||
void removeCharacterAppearanceScript();
|
||||
|
||||
void loadCharacterAppearance(bool blockingCall);
|
||||
void loadCharacterAppearanceScript(shared_ptr<Instance> asset);
|
||||
|
||||
static void onLocalPlayerNotIdle(RBX::ServiceProvider* serviceProvider);
|
||||
|
||||
void renderDPhysicsRegion(Adorn* adorn);
|
||||
void renderStreamedRegion(Adorn* adorn);
|
||||
void renderPartMovementPath(Adorn* adorn);
|
||||
|
||||
static bool physicsOutBandwidthExceeded(const RBX::Instance* context);
|
||||
static double getNetworkBufferHealth(const RBX::Instance* context);
|
||||
void reportStat(std::string stat);
|
||||
|
||||
void addToLoadingInstances(int newInstances) { loadingInstances += newInstances; }
|
||||
void removeFromLoadingInstances(int oldInstances) { loadingInstances -= oldInstances; }
|
||||
int getLoadingInstances() { return loadingInstances; }
|
||||
|
||||
bool getAppearanceDidLoad() const { return appearanceDidLoad; }
|
||||
bool getAppearanceDidLoadNonConst() { return appearanceDidLoad; }
|
||||
void setAppearanceDidLoad(bool value);
|
||||
bool getCharacterAppearanceLoaded() const { return characterAppearanceLoaded; }
|
||||
void setCharacterAppearanceLoaded(bool value);
|
||||
|
||||
void onFriendStatusChanged(shared_ptr<Instance> player, FriendService::FriendStatus friendStatus);
|
||||
FriendService::FriendStatus getFriendStatus(shared_ptr<Instance> player);
|
||||
void isFriendsWith(int otherUserId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void isBestFriendsWith(int otherUserId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void isInGroup(int groupId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void getRankInGroup(int groupId, boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void getRoleInGroup(int groupId, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void getFriendsOnline(int maxFriends, boost::function<void(shared_ptr<const Reflection::ValueArray>)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
|
||||
void loadChatInfo();
|
||||
|
||||
// should be called with at least data model read lock
|
||||
bool isChatInfoValid() const;
|
||||
ChatFilterType getChatFilterType() const;
|
||||
|
||||
// for testing only
|
||||
void setChatInfo(ChatFilterType filterType);
|
||||
|
||||
void kick(std::string msg);
|
||||
void handleTeleportInternalSignal(TeleportService::TeleportState teleportState, shared_ptr<const Reflection::ValueTable> teleportInfo, shared_ptr<Instance> customLoadingGUI);
|
||||
void handleTeleportSignalBackend(TeleportService::TeleportState teleportState);
|
||||
void setForceEarlySpawnLocationCalculation();
|
||||
bool calculatesSpawnLocationEarly() const;
|
||||
|
||||
const RakNet::SystemAddress& getRemoteAddress() const;
|
||||
const SystemAddress getRemoteAddressAsRbxAddress() const;
|
||||
void setRemoteAddress(const RakNet::SystemAddress& address);
|
||||
|
||||
void onTeleport(TeleportService::TeleportState teleportState, int placeId, std::string instanceIdOrSpawnName);
|
||||
void onTeleportInternal(TeleportService::TeleportState teleportState, shared_ptr<const Reflection::ValueTable> teleportInfo, shared_ptr<Instance> customLoadingGUI = shared_ptr<Instance>());
|
||||
bool getTeleported() const { return teleported; }
|
||||
bool getTeleportedIn() const { return teleportedIn; }
|
||||
void setTeleportedIn(bool value);
|
||||
|
||||
int getFollowUserId() const { return followUserId; }
|
||||
void setFollowUserId(int followUserId) { this->followUserId = followUserId; }
|
||||
|
||||
void loadStarterGear();
|
||||
void onCharacterDied();
|
||||
|
||||
/*override*/ void destroy();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void setupHumanoid(shared_ptr<Humanoid> humanoid);
|
||||
void characterChildAdded(shared_ptr<Instance> child);
|
||||
|
||||
void doPeriodicIdleCheck();
|
||||
void checkContextReadyToSpawnCharacter();
|
||||
static void calculateNextSpawnLocationHelper(
|
||||
weak_ptr<Player>& weakPlayer, const ServiceProvider* serviceProvider);
|
||||
void calculateNextSpawnLocation(const ServiceProvider* serviceProvider);
|
||||
SpawnData calculateSpawnLocation(const std::string& preferedSpawnName);
|
||||
|
||||
static void loadChatInfoInternal(weak_ptr<Player> weakPlayer);
|
||||
|
||||
Time lastActivityTime;
|
||||
|
||||
MembershipType membershipType;
|
||||
int accountAge;
|
||||
|
||||
bool chatInfoHasBeenLoaded;
|
||||
ChatFilterType chatFilterType;
|
||||
|
||||
shared_ptr<RBX::Mouse> mouse;
|
||||
RBX::Camera::CameraMode cameraMode;
|
||||
|
||||
float nameDisplayDistance;
|
||||
float healthDisplayDistance;
|
||||
float cameraMaxZoomDistance;
|
||||
float cameraMinZoomDistance;
|
||||
bool enableMouseLockOption;
|
||||
RBX::StarterPlayerService::DeveloperTouchCameraMovementMode touchCameraMovementMode;
|
||||
RBX::StarterPlayerService::DeveloperComputerCameraMovementMode computerCameraMovementMode;
|
||||
RBX::StarterPlayerService::DeveloperCameraOcclusionMode cameraOcclusionMode;
|
||||
RBX::StarterPlayerService::DeveloperTouchMovementMode touchMovementMode;
|
||||
RBX::StarterPlayerService::DeveloperComputerMovementMode computerMovementMode;
|
||||
|
||||
bool copiedGuiOnce;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
@@ -0,0 +1,452 @@
|
||||
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "V8Tree/Instance.h"
|
||||
#include "V8Tree/Service.h"
|
||||
#include "Network/Player.h"
|
||||
#include "Network/ChatFilter.h"
|
||||
#include "Util/SystemAddress.h"
|
||||
#include "Util/GameMode.h"
|
||||
#include "V8DataModel/FriendService.h"
|
||||
#include "V8DataModel/ContentProvider.h"
|
||||
#include "boost/thread/thread.hpp"
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <queue>
|
||||
|
||||
namespace RakNet {
|
||||
class RakPeerInterface;
|
||||
struct Packet;
|
||||
class BitStream;
|
||||
struct SystemAddress;
|
||||
}
|
||||
|
||||
namespace RBX {
|
||||
class PartInstance;
|
||||
class ModelInstance;
|
||||
class Region2;
|
||||
class Adorn;
|
||||
class ScriptInformationProvider;
|
||||
class DataModel;
|
||||
|
||||
namespace Network {
|
||||
|
||||
struct MemHash
|
||||
{
|
||||
size_t checkIdx;
|
||||
unsigned int value;
|
||||
unsigned int failMask;
|
||||
};
|
||||
|
||||
typedef std::vector<MemHash> MemHashVector;
|
||||
typedef std::vector<MemHashVector> MemHashConfigs;
|
||||
|
||||
class ConcurrentRakPeer;
|
||||
|
||||
class ChatMessage
|
||||
{
|
||||
public:
|
||||
enum ChatType
|
||||
{
|
||||
CHAT_TYPE_ALL,
|
||||
CHAT_TYPE_TEAM,
|
||||
CHAT_TYPE_WHISPER,
|
||||
CHAT_TYPE_GAME,
|
||||
//CHAT_TYPE_PARTY
|
||||
};
|
||||
|
||||
std::string guid;
|
||||
std::string message;
|
||||
ChatType chatType;
|
||||
shared_ptr<Player> const source;
|
||||
shared_ptr<Player> const destination;
|
||||
ChatMessage(const ChatMessage& other, const std::string& message);
|
||||
ChatMessage(const char* message, ChatType chatType, shared_ptr<Player> source);
|
||||
ChatMessage(const char* message, ChatType chatType, shared_ptr<Player> source, shared_ptr<Player> destination);
|
||||
|
||||
bool isVisibleToPlayer(shared_ptr<Player> player) const;
|
||||
static bool isVisibleToPlayer(shared_ptr<Player> const player, shared_ptr<Player> const source, shared_ptr<Player> const destination, const ChatType chatType);
|
||||
std::string getReportAbuseMessage() const;
|
||||
};
|
||||
|
||||
struct AbuseReport
|
||||
{
|
||||
struct Message
|
||||
{
|
||||
int userID;
|
||||
std::string text;
|
||||
std::string guid;
|
||||
};
|
||||
|
||||
int placeID;
|
||||
std::string gameJobID;
|
||||
|
||||
int submitterID;
|
||||
int allegedAbuserID;
|
||||
std::string comment;
|
||||
std::list< Message > messages;
|
||||
void addMessage(shared_ptr<Player> reportingPlayer, const ChatMessage& cm);
|
||||
};
|
||||
|
||||
class AbuseReporter
|
||||
{
|
||||
struct data
|
||||
{
|
||||
std::queue<AbuseReport> queue;
|
||||
boost::mutex requestSync; // synchronizes the request queue
|
||||
};
|
||||
shared_ptr<data> _data;
|
||||
scoped_ptr<worker_thread> requestProcessor;
|
||||
public:
|
||||
AbuseReporter(std::string abuseUrl);
|
||||
void add(AbuseReport& r, shared_ptr<Player> reportingPlayer, const std::list<ChatMessage>& chatHistory);
|
||||
private:
|
||||
static worker_thread::work_result processRequests(shared_ptr<data> _data, std::string abuseUrl);
|
||||
};
|
||||
|
||||
extern const char* const sPlayers;
|
||||
|
||||
class Players
|
||||
: public DescribedNonCreatable<Players, Instance, sPlayers>
|
||||
, public Service
|
||||
{
|
||||
private:
|
||||
typedef DescribedNonCreatable<Players, Instance, sPlayers> Super;
|
||||
public:
|
||||
// Unfortunately the RakNet enums are not accessible via the Players class, so this identical enum is created
|
||||
// and mapped in PluginInterfaceAdapter::OnReceive. - Tim
|
||||
enum ReceiveResult
|
||||
{
|
||||
// The plugin used this message and it shouldn't be given to the user.
|
||||
PLAYERS_STOP_PROCESSING_AND_DEALLOCATE=0,
|
||||
|
||||
// The plugin is going to hold on to this message. Do not deallocate it but do not pass it to other plugins either.
|
||||
PLAYERS_STOP_PROCESSING,
|
||||
};
|
||||
|
||||
enum ChatOption
|
||||
{
|
||||
CLASSIC_CHAT = 0,
|
||||
BUBBLE_CHAT = 1,
|
||||
CLASSIC_AND_BUBBLE_CHAT = 2
|
||||
};
|
||||
|
||||
enum PlayerChatType
|
||||
{
|
||||
PLAYER_CHAT_TYPE_ALL = 0,
|
||||
PLAYER_CHAT_TYPE_TEAM = 1,
|
||||
PLAYER_CHAT_TYPE_WHISPER= 2
|
||||
};
|
||||
|
||||
|
||||
static bool isNetworkClient(Instance* instance);
|
||||
void friendEventFired(int userId, int otherUserId, FriendService::FriendEventType friendEvent);
|
||||
void friendStatusChanged(int userId, int otherUserId, FriendService::FriendStatus friendStatus);
|
||||
|
||||
private:
|
||||
std::string saveDataUrl;
|
||||
std::string loadDataUrl;
|
||||
std::string saveLeaderboardDataUrl;
|
||||
boost::unordered_set<std::string> leaderboardKeys;
|
||||
|
||||
std::string chatFilterUrl;
|
||||
std::string buildUserPermissionsUrl;
|
||||
std::string sysStatsUrl;
|
||||
std::string goldenHash;
|
||||
std::string goldenHash2;
|
||||
std::string goldenHash3;
|
||||
|
||||
static bool canKickBecauseRunningInRealGameServer;
|
||||
static std::set<std::string> goldenHashes;
|
||||
static boost::mutex goldenHashesMutex;
|
||||
|
||||
static MemHashConfigs goldMemHashes;
|
||||
static boost::mutex goldMemHashesMutex;
|
||||
|
||||
bool characterAutoSpawn;
|
||||
|
||||
scoped_ptr<AbuseReporter> abuseReporter;
|
||||
boost::intrusive_ptr<GuidItem<Instance>::Registry> guidRegistry;
|
||||
std::list<ChatMessage> chatHistory;
|
||||
|
||||
const boost::intrusive_ptr<GuidItem<Instance>::Registry>& getGuidRegistry();
|
||||
|
||||
copy_on_write_ptr<Instances> players;
|
||||
ConcurrentRakPeer* rakPeer;
|
||||
|
||||
int maxPlayers;
|
||||
int preferredPlayers;
|
||||
int testPlayerNameId;
|
||||
int testPlayerUserId;
|
||||
shared_ptr<Player> localPlayer;
|
||||
|
||||
ChatOption chatOption;
|
||||
|
||||
bool nonSuperSafeChatForAllPlayersEnabled;
|
||||
|
||||
rbx::signals::connection blockUserClientSignalConnection;
|
||||
rbx::signals::connection blockUserFinishedFromServerConnection;
|
||||
rbx::signals::connection loadLocalPlayerGuisConnection;
|
||||
|
||||
boost::unordered_map<std::pair<int,int>, std::pair<boost::function<void(std::string)>, boost::function<void(std::string)> > > clientBlockUserMap;
|
||||
|
||||
void raiseChatMessageSignal(const ChatMessage& message);
|
||||
void raisePlayerChattedSignal(const ChatMessage& message);
|
||||
|
||||
void loadLocalPlayerGuis();
|
||||
void gotBlockUserSuccess(std::string response, bool blockUser, int blockerUserId, int blockeeUserId, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void gotBlockUserError(std::string error, bool blockUser, int blockerUserId, int blockeeUserId, boost::function<void(std::string)> errorFunction);
|
||||
|
||||
static void onReceivedRawGetUserIdSuccess(weak_ptr<DataModel> weakDataModel, std::string response, boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
static void onReceivedRawGetUserIdError(weak_ptr<DataModel> weakDataModel, std::string error, boost::function<void(std::string)> errorFunction);
|
||||
|
||||
static void onReceivedRawGetUserNameSuccess(weak_ptr<DataModel> weakDataModel, std::string response, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
static void onReceivedRawGetUserNameError(weak_ptr<DataModel> weakDataModel, std::string error, boost::function<void(std::string)> errorFunction);
|
||||
|
||||
void serverMakeBlockUserRequest(bool blockUser, int blockerUserId, int blockeeUserId, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void clientReceiveBlockUserFinished(int blockerUserId, int blockeeUserId, std::string errorString);
|
||||
|
||||
void internalBlockUser(int blockerUserId, int blockeeUserId, bool isBlocking, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
|
||||
public:
|
||||
ReceiveResult OnReceiveChat(Player* sourceValidation, RakNet::RakPeerInterface* peer, RakNet::Packet* packet, unsigned char chatType);
|
||||
ReceiveResult OnReceiveReportAbuse(Player* source, RakNet::RakPeerInterface* peer, RakNet::Packet* packet);
|
||||
|
||||
rbx::signal<void(shared_ptr<Instance>,shared_ptr<Instance>,FriendService::FriendEventType)> friendRequestEvent;
|
||||
rbx::signal<void(shared_ptr<Instance>)> playerAddedEarlySignal;
|
||||
rbx::signal<void(shared_ptr<Instance>)> playerAddedSignal;
|
||||
rbx::signal<void(shared_ptr<Instance>)> playerRemovingSignal;
|
||||
rbx::signal<void(shared_ptr<Instance>)> playerRemovingLateSignal;
|
||||
rbx::signal<void(const ChatMessage&)> chatMessageSignal;
|
||||
rbx::signal<void(AbuseReport report)> abuseReportedReceived;
|
||||
rbx::signal<void(const RakNet::SystemAddress&, const shared_ptr<RakNet::BitStream>&, const shared_ptr<Instance>, const std::string&, const std::string&)> sendFilteredChatMessageSignal;
|
||||
|
||||
rbx::signal<void(PlayerChatType, shared_ptr<Instance>, std::string, shared_ptr<Instance>)> playerChattedSignal;
|
||||
rbx::signal<void(std::string)> gameAnnounceSignal;
|
||||
|
||||
rbx::remote_signal<void(int,int,bool)> blockUserRequestFromClientSignal;
|
||||
rbx::remote_signal<void(int,int,std::string)> blockUserFinishedFromServerSignal;
|
||||
rbx::remote_signal<void(int)> requestCloudEditKick;
|
||||
rbx::remote_signal<void()> requestCloudEditShutdown;
|
||||
|
||||
static Reflection::RefPropDescriptor<Players, Instance> propLocalPlayer;
|
||||
static Reflection::PropDescriptor<Players, bool> propCharacterAutoSpawn;
|
||||
static Reflection::RemoteEventDesc<Players, void(int)> event_requestCloudEditKick;
|
||||
static Reflection::RemoteEventDesc<Players, void()> event_requestCloudEditShutdown;
|
||||
Players();
|
||||
~Players();
|
||||
|
||||
bool superSafeOn() const;
|
||||
|
||||
shared_ptr<Instance> createLocalPlayer(int userId, bool teleportedIn = false);
|
||||
void resetLocalPlayer();
|
||||
|
||||
Player* getLocalPlayer() {return localPlayer.get();}
|
||||
const Player* getConstLocalPlayer() const {return localPlayer.get();}
|
||||
Instance* getLocalPlayerDangerous() const; // only for reflection
|
||||
|
||||
int getNumPlayers() const { return (int) players->size(); }
|
||||
|
||||
void getUserIdFromName(std::string userName, boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void getNameFromUserId(int userId, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
void getFriends(int userId, boost::function<void(shared_ptr<Instance>) > resumeFunction, boost::function<void(std::string)> errorFunction);
|
||||
|
||||
static void setAppearanceParent(shared_ptr<Instance> model, weak_ptr<Instance> instance);
|
||||
static void doLoadAppearance(AsyncHttpQueue::RequestResult result, shared_ptr<Instances> instances, std::string contentDescription, shared_ptr<ModelInstance> model, shared_ptr<int> amountToLoad, boost::function<void (shared_ptr<Instance>)> resumeFunction, boost::function<void (std::string)> errorFunction);
|
||||
static void doMakeAccoutrementRequests(std::string response, weak_ptr<DataModel> dataModel, shared_ptr<ModelInstance> model, boost::function<void (shared_ptr<Instance>)> resumeFunction, boost::function<void (std::string)> errorFunction);
|
||||
static void makeAccoutrementRequests(std::string *response, std::exception *err, weak_ptr<DataModel> dataModel, shared_ptr<ModelInstance> model, boost::function<void (shared_ptr<Instance>)> resumeFunction, boost::function<void (std::string)> errorFunction);
|
||||
void getCharacterAppearance(int userId, boost::function<void (shared_ptr<Instance>)> resumeFunction, boost::function<void (std::string)> errorFunction);
|
||||
|
||||
int getMaxPlayers() const;
|
||||
int getPreferredPlayers() const;
|
||||
|
||||
void setMaxPlayers(int value);
|
||||
void setPreferredPlayers(int value);
|
||||
void setSysStatsUrl(std::string url);
|
||||
void setSysHash(std::string hash);
|
||||
|
||||
void setGoldenHashes(const std::string& windowsHash, const std::string& macHash, const std::string& windowsPlayerBetaHash);
|
||||
static void setGoldenHashes2(const std::set<std::string>& hashes);
|
||||
static void setGoldMemHashes(const MemHashConfigs& hashes);
|
||||
|
||||
std::string getSaveDataUrl(int userId) const;
|
||||
void setSaveDataUrl(std::string saveDataUrl);
|
||||
|
||||
std::string getLoadDataUrl(int userId) const;
|
||||
void setLoadDataUrl(std::string loadDataUrl);
|
||||
|
||||
std::string getSaveLeaderboardDataUrl(int userId) const;
|
||||
void setSaveLeaderboardDataUrl(std::string saveLeaderboardDataUrl);
|
||||
void addLeaderboardKey(std::string);
|
||||
|
||||
bool hasLeaderboardKey(const std::string& key) const;
|
||||
boost::unordered_set<std::string>::const_iterator beginLeaderboardKey() const;
|
||||
boost::unordered_set<std::string>::const_iterator endLeaderboardKey() const;
|
||||
|
||||
void setChatOption(ChatOption value);
|
||||
void setNonSuperSafeChatForAllPlayersEnabled(bool enabled);
|
||||
bool getNonSuperSafeChatForAllPlayersEnabled() const;
|
||||
bool getClassicChat() const { return chatOption == CLASSIC_CHAT || chatOption == CLASSIC_AND_BUBBLE_CHAT; }
|
||||
bool getBubbleChat() const { return chatOption == BUBBLE_CHAT || chatOption == CLASSIC_AND_BUBBLE_CHAT; }
|
||||
|
||||
shared_ptr<const Instances> getPlayers() { return players.read(); }
|
||||
|
||||
// Chat-related functions
|
||||
void gamechat(const std::string& message);
|
||||
|
||||
void chat(std::string message);
|
||||
void teamChat(std::string);
|
||||
void whisperChat(std::string message, shared_ptr<Instance> player);
|
||||
|
||||
void reportAbuse(Player* player, const std::string& comment);
|
||||
void reportAbuseLua(shared_ptr<Instance> instance, std::string reason, std::string comment);
|
||||
std::list<ChatMessage>::const_iterator chatHistory_begin() { return chatHistory.begin(); }
|
||||
std::list<ChatMessage>::const_iterator chatHistory_end() { return chatHistory.end(); }
|
||||
bool canReportAbuse() const;
|
||||
void setAbuseReportUrl(std::string value);
|
||||
void setChatFilterUrl(std::string value);
|
||||
void setBuildUserPermissionsUrl(std::string value);
|
||||
bool hasBuildUserPermissionsUrl() const;
|
||||
std::string getBuildUserPermissionsUrl(int playerId) const;
|
||||
|
||||
void friendServiceRequest(bool makeFriends, weak_ptr<Player> sourcePlayer, int otherUserId);
|
||||
|
||||
bool getCharacterAutoSpawnProperty() const { return characterAutoSpawn; }
|
||||
void setCharacterAutoSpawnProperty(bool value);
|
||||
bool getShouldAutoSpawnCharacter() const;
|
||||
|
||||
void blockUser(int blockerUserId, int blockeeUserId,
|
||||
boost::function<void(std::string)> resumeFunction = boost::function<void(bool)>(),
|
||||
boost::function<void(std::string)> errorFunction = boost::function<void(std::string)>());
|
||||
void unblockUser(int blockerUserId, int blockeeUserId,
|
||||
boost::function<void(std::string)> resumeFunction = boost::function<void(bool)>(),
|
||||
boost::function<void(std::string)> errorFunction = boost::function<void(std::string)>());
|
||||
|
||||
void setConnection(ConcurrentRakPeer* rakPeer);
|
||||
|
||||
shared_ptr<Instance> playerFromCharacter(shared_ptr<Instance> character);
|
||||
shared_ptr<Instance> getPlayerInstanceByID(int userID);
|
||||
shared_ptr<Player> getPlayerByID(int userID);
|
||||
|
||||
static Player* getPlayerFromCharacter(RBX::Instance* character);
|
||||
|
||||
void buildClientRegion(Region2& clientRegion);
|
||||
|
||||
void renderDPhysicsRegions(Adorn* adorn);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// STATICS
|
||||
//
|
||||
// If Client == Client Network Address; If Server == NetworkOwner::Server()
|
||||
static RBX::SystemAddress findLocalSimulatorAddress(const RBX::Instance* context);
|
||||
|
||||
static ModelInstance* findLocalCharacter(RBX::Instance* context);
|
||||
static const ModelInstance* findConstLocalCharacter(const RBX::Instance* context);
|
||||
|
||||
static Player* findLocalPlayer(RBX::Instance* context);
|
||||
static const Player* findConstLocalPlayer(const RBX::Instance* context);
|
||||
|
||||
static shared_ptr<Player> findAncestorPlayer(const RBX::Instance* context);
|
||||
|
||||
static shared_ptr<Player> findPlayerWithAddress(const RBX::SystemAddress& playerAddres, const RBX::Instance* context);
|
||||
|
||||
static bool clientIsPresent(const RBX::Instance* context, bool testInDatamodel = true);
|
||||
|
||||
static bool serverIsPresent(const RBX::Instance* context, bool testInDatamodel = true);
|
||||
|
||||
static bool frontendProcessing(const RBX::Instance* context, bool testInDatamodel = true);
|
||||
|
||||
static bool backendProcessing(const RBX::Instance* context, bool testInDatamodel = true);
|
||||
|
||||
static int getPlayerCount(const RBX::Instance* context);
|
||||
|
||||
// TODO: Remove this some day!
|
||||
static bool getDistributedPhysicsEnabled();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// These are here as "official" designation of Big-Picture states
|
||||
//
|
||||
// Frontend Backend
|
||||
// GameServer: x serverIsPresent (assumes !findLocalPlayer)
|
||||
// Visit Online: x clientIsPresent && findLocalPlayer
|
||||
// Watch Online: x clientIsPresent && !findLocalPlayer (i.e. - visit, no character)
|
||||
// Visit Solo: x x !clientIsPresent && !serverIsPresent && findLocalPlayer
|
||||
// Local Play: x clientIsPresent && findLocalPlayer && userID == 0
|
||||
// Edit Mode: x x !clientIsPresent && !serverIsPresent && !findLocalPlayer
|
||||
//
|
||||
// typedef enum {GAME_SERVER, DPHYS_GAME_SERVER, CLIENT, DPHYS_CLIENT, WATCH_ONLINE, VISIT_SOLO, EDIT} GameMode;
|
||||
|
||||
static RBX::Network::GameMode getGameMode(const RBX::Instance* context)
|
||||
{
|
||||
bool client = clientIsPresent(context);
|
||||
bool server = serverIsPresent(context);
|
||||
bool localPlayer = (findConstLocalPlayer(context) != NULL);
|
||||
bool dPhysics = getDistributedPhysicsEnabled();
|
||||
|
||||
RBXASSERT(!(server && (client || localPlayer)));
|
||||
|
||||
if (server) {return dPhysics ? DPHYS_GAME_SERVER : GAME_SERVER;}
|
||||
if (client && localPlayer) {return dPhysics ? DPHYS_CLIENT : CLIENT;}
|
||||
if (client && !localPlayer) {return WATCH_ONLINE;}
|
||||
if (!client && localPlayer) {return VISIT_SOLO;}
|
||||
else {return EDIT;}
|
||||
}
|
||||
|
||||
static RBX::Network::GameMode getGameMode(const RBX::Instance* context, const int placeID)
|
||||
{
|
||||
bool client = clientIsPresent(context);
|
||||
bool server = serverIsPresent(context);
|
||||
bool localPlayer = ( findConstLocalPlayer(context) != NULL);
|
||||
bool dPhysics = getDistributedPhysicsEnabled();
|
||||
|
||||
RBXASSERT(!(server && (client || localPlayer)));;
|
||||
|
||||
if (placeID <= 0) {return LOCAL_PLAY;}
|
||||
if (server) {return dPhysics ? DPHYS_GAME_SERVER : GAME_SERVER;}
|
||||
if (client && localPlayer) {return dPhysics ? DPHYS_CLIENT : CLIENT;}
|
||||
if (client && !localPlayer) {return WATCH_ONLINE;}
|
||||
if (!client && localPlayer) {return VISIT_SOLO;}
|
||||
else {return EDIT;}
|
||||
}
|
||||
|
||||
static bool isCloudEdit(const RBX::Instance* context);
|
||||
|
||||
void onRemoteSysStats(int userId, const std::string& stat, const std::string& message, bool desireKick = true);
|
||||
bool hashMatches(const std::string& hash);
|
||||
static unsigned int checkGoldMemHashes(const std::vector<unsigned int>& hashes);
|
||||
|
||||
void disconnectPlayer(int userId, int reason);
|
||||
void disconnectPlayerLocal(int userId, int reason);
|
||||
|
||||
bool getUseCoreScriptHealthBar();
|
||||
|
||||
protected:
|
||||
void disconnectPlayer(Instance& instance, int userId, int reason);
|
||||
|
||||
std::map<int, std::set<std::string> > cheatingPlayers;
|
||||
bool askAddChild(const Instance* instance) const;
|
||||
/*override*/ void onChildAdded(Instance* child);
|
||||
/*override*/ void onChildRemoving(Instance* child);
|
||||
/*override*/ void onDescendantRemoving(const shared_ptr<Instance>& instance);
|
||||
/*override*/ void processRemoteEvent(const Reflection::EventDescriptor& descriptor, const Reflection::EventArguments& args, const RBX::SystemAddress& source);
|
||||
|
||||
private:
|
||||
void reportScriptSecurityError(int userId, std::string hash, std::string error, std::string stack);
|
||||
|
||||
void killPlayer(int userId);
|
||||
|
||||
void addChatMessage(const ChatMessage& message);
|
||||
|
||||
void checkChat(const std::string& message);
|
||||
|
||||
void sendFilteredChatMessageSignalHelper(const RakNet::SystemAddress& systemAddress,
|
||||
const shared_ptr<RakNet::BitStream>& baseData, const shared_ptr<Instance> sourceInstance, shared_ptr<ChatMessage> chatEvent, const ChatFilter::Result& response);
|
||||
|
||||
// Instance
|
||||
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
|
||||
};
|
||||
|
||||
} }
|
||||
@@ -0,0 +1,396 @@
|
||||
/* Copyright 2003-2006 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
//#include "Util/Velocity.h"
|
||||
#include "bitstream.h"
|
||||
|
||||
//#include "Dictionary.h"
|
||||
#include "Util.h"
|
||||
|
||||
namespace RBX
|
||||
{
|
||||
namespace Network
|
||||
{
|
||||
// --------------------------------------------------------------------
|
||||
// reverseEndian
|
||||
//
|
||||
// Reuse the numeric constants as much as possible to reduce constant value loads.
|
||||
|
||||
template <unsigned int Bytes> struct ReverseEndianBytes
|
||||
{
|
||||
template <class T>
|
||||
static inline void reverseEndian(T& result) {
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == 1 );
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct ReverseEndianBytes<2>
|
||||
{
|
||||
template <class T>
|
||||
static inline void reverseEndian(T& x) {
|
||||
uint16_t& result = (uint16_t&)x;
|
||||
result = (result << 8) | (result >> 8);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct ReverseEndianBytes<4>
|
||||
{
|
||||
template <class T>
|
||||
static inline void reverseEndian(T& x) {
|
||||
uint32_t& result = (uint32_t&)x;
|
||||
uint32_t val = ((result & 0x00FF00FF) << 8) | ((result >> 8) & 0x00FF00FF);
|
||||
result = (val << 16) | (val >> 16);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct ReverseEndianBytes<8>
|
||||
{
|
||||
template <class T>
|
||||
static inline void reverseEndian(T& x) {
|
||||
uint64_t& result = (uint64_t&)x;
|
||||
uint64_t val = (result << 32) | (result >> 32);
|
||||
val = (val & 0x0000FFFF0000FFFF) << 16 | ((val >> 16) & 0x0000FFFF0000FFFF);
|
||||
val = (val & 0x00FF00FF00FF00FF) << 8 | ((val >> 8 ) & 0x00FF00FF00FF00FF);
|
||||
result = val;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline void reverseEndianBits(T& result, unsigned int bits ) {
|
||||
unsigned int msbPad = (-(signed int)bits)&7; // == (8-(bits&7))&7. High bits that were truncated off the MSB.
|
||||
|
||||
// Shift up by the amount clipped off the non-zero-MSB.
|
||||
T shifted = result << msbPad;
|
||||
|
||||
// Right align the non-zero-MSB while it is still in the LSB and easy to locate.
|
||||
result = (shifted & ~(T)0xff) | (result & ((T)0xff >> msbPad));
|
||||
|
||||
if( (sizeof(T)*8-7) <= bits )
|
||||
{
|
||||
ReverseEndianBytes<sizeof(T)>::reverseEndian( result );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Warning: Taking the address of a parameter forces a register spill.
|
||||
unsigned char* a = (unsigned char*)&result;
|
||||
unsigned char* b = a + ((bits-1) >> 3);
|
||||
while( a < b )
|
||||
{
|
||||
unsigned char t = *a;
|
||||
*a++ = *b;
|
||||
*b-- = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
template <unsigned int Bytes> struct ReadFastBytes
|
||||
{
|
||||
template <class T>
|
||||
static inline void readFast(RakNet::BitStream& bitStream, T& result, unsigned int bits)
|
||||
{
|
||||
unsigned int readOffset = bitStream.GetReadOffset();
|
||||
|
||||
if (readOffset + bits > bitStream.GetNumberOfBitsUsed())
|
||||
throw RBX::network_stream_exception("readFast past end");
|
||||
|
||||
const unsigned char* data = bitStream.GetData();
|
||||
const unsigned char* pos = data + (readOffset >> 3);
|
||||
|
||||
unsigned int bitsOffset = readOffset & 7;
|
||||
unsigned int firstByteBits = 8 - bitsOffset;
|
||||
|
||||
unsigned char firstByte = *pos & (0xff >> bitsOffset);
|
||||
|
||||
if(firstByteBits >= bits)
|
||||
{
|
||||
result = (T)(firstByte >> (firstByteBits - bits));
|
||||
bitStream.SetReadOffset(readOffset + bits);
|
||||
return;
|
||||
}
|
||||
|
||||
T tmp = (T)firstByte;
|
||||
++pos;
|
||||
|
||||
unsigned int bitsRemaining = bits - firstByteBits; // 8 could be propagated out.
|
||||
for(; bitsRemaining > 8; bitsRemaining -= 8)
|
||||
{
|
||||
tmp = (tmp << 8) | *pos;
|
||||
++pos;
|
||||
}
|
||||
|
||||
tmp = (tmp << bitsRemaining) | (*pos >> (8 - bitsRemaining));
|
||||
result = tmp;
|
||||
|
||||
bitStream.SetReadOffset(readOffset + bits);
|
||||
}
|
||||
|
||||
|
||||
template <unsigned int Bits, class T>
|
||||
static inline void readFast(RakNet::BitStream& bitStream, T& result)
|
||||
{
|
||||
readFast(bitStream, result, Bits);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ReadFastBytes<1>
|
||||
{
|
||||
template <unsigned int Bits, class T>
|
||||
static inline void readFast(RakNet::BitStream& bitStream, T& result)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(Bits >= 1 && Bits <= 8);
|
||||
|
||||
unsigned int readOffset = bitStream.GetReadOffset();
|
||||
|
||||
if (readOffset + (Bits+8) > bitStream.GetNumberOfBitsUsed())
|
||||
{
|
||||
// Avoid crashing due to reading an extra byte off the end of the buffer.
|
||||
ReadFastBytes<0>::readFast(bitStream, result, Bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* data = bitStream.GetData();
|
||||
|
||||
unsigned int readOffsetBytes = readOffset >> 3;
|
||||
|
||||
unsigned char byte0 = data[readOffsetBytes + 0];
|
||||
unsigned char byte1 = data[readOffsetBytes + 1];
|
||||
|
||||
result = (((((byte0 << 8) | byte1) << (readOffset & 7)) & 0xffff) >> (16 - Bits) );
|
||||
|
||||
bitStream.SetReadOffset(readOffset + Bits);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ReadFastBytes<2>
|
||||
{
|
||||
template <unsigned int Bits, class T>
|
||||
static inline void readFast(RakNet::BitStream& bitStream, T& result)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(Bits >= 9 && Bits <= 16);
|
||||
|
||||
unsigned int readOffset = bitStream.GetReadOffset();
|
||||
|
||||
if (readOffset + (Bits+8) > bitStream.GetNumberOfBitsUsed())
|
||||
{
|
||||
// Avoid crashing due to reading an extra byte off the end of the buffer.
|
||||
ReadFastBytes<0>::readFast(bitStream, result, Bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* data = bitStream.GetData();
|
||||
|
||||
unsigned int readOffsetBytes = readOffset >> 3;
|
||||
|
||||
unsigned char byte0 = data[readOffsetBytes + 0];
|
||||
unsigned char byte1 = data[readOffsetBytes + 1];
|
||||
unsigned char byte2 = data[readOffsetBytes + 2];
|
||||
|
||||
result = ((((byte0 << 16) | (byte1 << 8) | byte2) << (readOffset & 7)) & 0xffffff) >> (24 - Bits);
|
||||
|
||||
bitStream.SetReadOffset(readOffset + Bits);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ReadFastBytes<4>
|
||||
{
|
||||
template <unsigned int Bits, class T>
|
||||
static inline void readFast(RakNet::BitStream& bitStream, T& result)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(Bits >= 17 && Bits <= 32);
|
||||
|
||||
unsigned int readOffset = bitStream.GetReadOffset();
|
||||
|
||||
if (readOffset + (Bits+8) > bitStream.GetNumberOfBitsUsed())
|
||||
{
|
||||
// Avoid crashing due to reading an extra byte off the end of the buffer.
|
||||
ReadFastBytes<0>::readFast(bitStream, result, Bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* data = bitStream.GetData();
|
||||
|
||||
unsigned int readOffsetBytes = readOffset >> 3;
|
||||
|
||||
unsigned char byte0 = data[readOffsetBytes + 0];
|
||||
unsigned char byte1 = data[readOffsetBytes + 1];
|
||||
unsigned char byte2 = data[readOffsetBytes + 2];
|
||||
unsigned char byte3 = data[readOffsetBytes + 3];
|
||||
unsigned char byte4 = data[readOffsetBytes + 4];
|
||||
|
||||
T tmp0 = (((((byte0 << 16) | (byte1 << 8) | byte2) << (readOffset & 7)) & 0xffffff) >> (24 - 16));
|
||||
T tmp1 = (((((byte2 << 16) | (byte3 << 8) | byte4) << (readOffset & 7)) & 0xffffff) >> (24 - (Bits - 16)));
|
||||
result = (tmp0 << 16) | tmp1;
|
||||
|
||||
bitStream.SetReadOffset(readOffset + Bits);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// The non-"T" versions replace ReadBits versions which did not do
|
||||
// endian swapping
|
||||
|
||||
template <class T>
|
||||
inline void readFastN(RakNet::BitStream& bitStream, T& result, unsigned int bits) {
|
||||
// Use default implementation for arbitrary bit-counts.
|
||||
ReadFastBytes<0>::readFast(bitStream, result, bits);
|
||||
|
||||
reverseEndianBits( result, bits );
|
||||
}
|
||||
|
||||
// The base template should only be needed for unusual numbers of bits.
|
||||
template <unsigned int Bits, class T>
|
||||
inline void readFastN(RakNet::BitStream& bitStream, T& result) {
|
||||
ReadFastBytes<0>::readFast<Bits>(bitStream, result);
|
||||
|
||||
reverseEndianBits( result, Bits );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// readFastT
|
||||
//
|
||||
// The "T" versions do not do endian swapping because the BitStream::Write
|
||||
// sends across network order/big-endian data.
|
||||
|
||||
template <class T>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, T& result)
|
||||
{
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == 0 ); // This is undefined.
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, bool& result)
|
||||
{
|
||||
unsigned int readOffset = bitStream.GetReadOffset();
|
||||
|
||||
if (readOffset + 1 > bitStream.GetNumberOfBitsUsed())
|
||||
throw RBX::network_stream_exception("readFastBool past end");
|
||||
|
||||
const unsigned char* data = bitStream.GetData();
|
||||
|
||||
bool tmp = (data[readOffset >> 3] & (0x80 >> (readOffset & 7))) != 0;
|
||||
result = tmp;
|
||||
|
||||
bitStream.SetReadOffset(readOffset + 1);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, float& result) {
|
||||
union { float f; uint32_t i; } t;
|
||||
ReadFastBytes<4>::readFast<32, uint32_t>(bitStream, t.i);
|
||||
result = t.f;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, double& result) {
|
||||
union { double d; uint64_t i; } t;
|
||||
ReadFastBytes<0>::readFast<64, uint64_t>(bitStream, t.i);
|
||||
result = t.d;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, int8_t& result) {
|
||||
ReadFastBytes<1>::readFast<8, uint8_t>(bitStream, (uint8_t&)result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, uint8_t& result) {
|
||||
ReadFastBytes<1>::readFast<8, uint8_t>(bitStream, result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, char& result) {
|
||||
ReadFastBytes<1>::readFast<8, uint8_t>(bitStream, (uint8_t&)result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, int16_t& result) {
|
||||
ReadFastBytes<2>::readFast<16, uint16_t>(bitStream, (uint16_t&)result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, uint16_t& result) {
|
||||
ReadFastBytes<2>::readFast<16, uint16_t>(bitStream, result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, int32_t& result) {
|
||||
ReadFastBytes<4>::readFast<32, uint32_t>(bitStream, (uint32_t&)result);
|
||||
}
|
||||
|
||||
#if defined(__LP64__)
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, long& result)
|
||||
{
|
||||
ReadFastBytes<0>::readFast<64, uint64_t>(bitStream, (uint64_t&)result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, unsigned long& result)
|
||||
{
|
||||
ReadFastBytes<0>::readFast<64, uint64_t>(bitStream, (uint64_t&)result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, RakNet::Time& result) {
|
||||
ReadFastBytes<0>::readFast<64, uint64_t>(bitStream, (uint64_t&)result);
|
||||
}
|
||||
#else
|
||||
// 32-bit long
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, long& result)
|
||||
{
|
||||
ReadFastBytes<4>::readFast<32, uint32_t>(bitStream, (uint32_t&)result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, unsigned long& result)
|
||||
{
|
||||
ReadFastBytes<4>::readFast<32, uint32_t>(bitStream, (uint32_t&)result);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, RakNet::Time& result)
|
||||
{
|
||||
ReadFastBytes<0>::readFast<64, uint64_t>(bitStream, (uint64_t&)result); // <-- FIXED
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
template <>
|
||||
inline void readFastT(RakNet::BitStream& bitStream, uint32_t& result) {
|
||||
ReadFastBytes<4>::readFast<32, uint32_t>(bitStream, result);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline void readVectorFast(RakNet::BitStream& bitStream, float& x, float& y, float& z)
|
||||
{
|
||||
float magnitude;
|
||||
readFastT(bitStream, magnitude);
|
||||
if (magnitude>0.00001f)
|
||||
{
|
||||
unsigned short c;
|
||||
readFastT(bitStream, c);
|
||||
x = (float(c) * (1.0f / 32767.5f) - 1.0f) * magnitude;
|
||||
|
||||
readFastT(bitStream, c);
|
||||
y = (float(c) * (1.0f / 32767.5f) - 1.0f) * magnitude;
|
||||
|
||||
readFastT(bitStream, c);
|
||||
z = (float(c) * (1.0f / 32767.5f) - 1.0f) * magnitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = y = z = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "network/ChatFilter.h"
|
||||
#include "Network/Player.h"
|
||||
#include "Util/Http.h"
|
||||
#include "util/HttpAux.h"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
static const std::string kWebChatWhiteListPolicy = "white";
|
||||
static const std::string kWebChatBlackListPolicy = "black";
|
||||
|
||||
namespace RBX
|
||||
{
|
||||
namespace Network
|
||||
{
|
||||
|
||||
class WebChatFilter : public RBX::Network::ChatFilter
|
||||
{
|
||||
public:
|
||||
/*override*/
|
||||
virtual void filterMessage(
|
||||
shared_ptr<RBX::Network::Player> sourcePlayer,
|
||||
shared_ptr<RBX::Instance> receiver,
|
||||
const std::string& message,
|
||||
const RBX::Network::ChatFilter::FilteredChatMessageCallback callback);
|
||||
}; // class WebChatFilter
|
||||
|
||||
void ConstructModerationFilterTextParamsAndHeaders(
|
||||
std::string text,
|
||||
int userID,
|
||||
int placeID,
|
||||
std::string gameInstanceID,
|
||||
|
||||
std::stringstream &outParams,
|
||||
RBX::HttpAux::AdditionalHeaders &outHeaders
|
||||
);
|
||||
|
||||
} // namespace Network
|
||||
} // namespace RBX
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Copyright 2003-2006 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace RBX
|
||||
{
|
||||
class Instance;
|
||||
class DataModel;
|
||||
namespace Network
|
||||
{
|
||||
typedef enum { Accept, Reject } FilterResult;
|
||||
|
||||
extern std::string versionB;
|
||||
extern std::string securityKey;
|
||||
bool isPlayerAuthenticationEnabled();
|
||||
void initWithoutSecurity(); // Used by Studio (so that it can't be used as a hack vector against RccService)
|
||||
void initWithPlayerSecurity(); // Used by Player
|
||||
void initWithServerSecurity(); // Used by RccService
|
||||
void initWithCloudEditSecurity(); // Used to set up cloud edit replication password
|
||||
bool isNetworkClient(const Instance* context);
|
||||
bool getSystemUrlLocal(DataModel *dataModel);
|
||||
void setSecurityVersions(const std::vector<std::string>& versions);
|
||||
|
||||
// Used for debugging and development:
|
||||
void setVersion(const char* version);
|
||||
|
||||
bool isTrustedContent(const char* url);
|
||||
}
|
||||
|
||||
void spawnDebugCheckThreads(boost::weak_ptr<RBX::DataModel> weakDataModel);
|
||||
extern unsigned int initialProgramHash;
|
||||
}
|
||||
Reference in New Issue
Block a user