/* Copyright 2003-2006 ROBLOX Corporation, All Rights Reserved */ #pragma once #include "Network/NetworkPacketCache.h" #include "Network/Player.h" #include "Peer.h" #include "Replicator.h" #include "Util/ProtectedString.h" #include "Util/standardout.h" #include "V8DataModel/PartInstance.h" #include "V8Tree/Service.h" #include "RakNet/Source/PluginInterface2.h" #include #include #include #include namespace RBX { namespace Network { class ServerReplicator; class NetworkOwnerJob; extern const char* const sServer; class Server : public DescribedCreatable , public Service { private: typedef DescribedCreatable Super; int outgoingPort; shared_ptr players; shared_ptr networkOwnerJob; bool isCloudEditServer; rbx::signals::scoped_connection itemAddedConnection; rbx::signals::scoped_connection workspaceLoadedConnection; static int lastId; bool isPlayerAuthenticationRequired; PhysicsPacketCache* physicsPacketCache; InstancePacketCache* instancePacketCache; NetworkSettings* networkSettings; struct LegalScript { std::string source; // cvx: Note that "bytecode" includes the strings tables, line info, etc... std::string currentBytecode; std::string legacyBytecode; }; std::vector legalScripts; boost::unordered_map scriptsBySource; boost::unordered_map scriptsByCurrentBytecode; boost::unordered_map scriptsByLegacyBytecode; boost::mutex placeAuthenticationResultCacheMutex; boost::unordered_map placeAuthenticationResultCache; public: static boost::function(RakNet::SystemAddress, Server*, NetworkSettings*)> createReplicator; // factory std::set usedTickets; std::set preusedTickets; bool getIsPlayerAuthenticationRequired() const { return Network::isPlayerAuthenticationEnabled() && isPlayerAuthenticationRequired; } void setIsPlayerAuthenticationRequired(bool value) { isPlayerAuthenticationRequired = value; } Server(); ~Server(); /*override*/ void onCreateRakPeer(); rbx::signal peer, FilterResult result, shared_ptr item, std::string member)> dataBasicFilteredSignal; rbx::signal peer, FilterResult result, shared_ptr item, std::string member)> dataCustomFilteredSignal; rbx::signal)> incommingConnectionSignal; static bool serverIsPresent(const Instance* context, bool testInDatamodel = true); ServerReplicator* findClientOwner(const Vector3& p); void start(int port, int threadSleepTime); void stop(int blockDuration = 1000); void configureAsCloudEditServer(); int getClientCount(); int getPort() const { return outgoingPort; } bool securityKeyMatches(const std::string& key); bool protocolVersionMatches(int protocolVersion); NetworkOwnerJob* getNetworkOwnerJob(); static void setAllowedSecurityVersions(const std::vector& versions); static std::vector getAllIPv4Addresses(); // script management bool isLegalReceiveInstance(Instance* instance) const; bool isScriptLegal(Instance* instance) const; boost::optional getScriptIndexForSource(const std::string& source) const; boost::optional getScriptIndexForBytecode(const std::string& bytecode, bool isCurrentFormat = true) const; boost::optional getScriptSourceForIndex(long index) const; boost::optional getScriptBytecodeForIndex(long index, bool isCurrentFormat = true) const; boost::optional getPlaceAuthenticationResultForOrigin(int originPlaceId); void registerPlaceAuthenticationResult(int originPlaceId, int result); /*override*/ RakNet::PluginReceiveResult OnReceive(RakNet::Packet *packet); bool isCloudEdit() const { return isCloudEditServer; } protected: virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider); bool askAddChild(const Instance* instance) const; private: void onItemAdded(shared_ptr item); void onWorkspaceLoaded(); boost::optional getScriptSourceFromInstance(Instance* instance) const; void registerLegalScript(const std::string& source); }; } }