This commit is contained in:
watrabi
2025-09-18 17:55:52 -04:00
commit 977f1ff4b8
15030 changed files with 17324420 additions and 0 deletions
+32
View File
@@ -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;
};
}}
+80
View File
@@ -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;
}
};
}
+76
View File
@@ -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
+71
View File
@@ -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;
};
}
+122
View File
@@ -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);
};
}
+103
View File
@@ -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 &regionId, 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 &regionId, RakNet::BitStream& bitStream, unsigned int numBits);
unsigned int getCachedBitStreamBytesUsed(const Key &regionId);
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;
};
}}
+70
View File
@@ -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);
};
}
}
+496
View File
@@ -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
+452
View File
@@ -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);
};
} }
+396
View File
@@ -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;
}
}
}
}
+41
View File
@@ -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
+37
View File
@@ -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;
}