#ifndef __RAK_SERVER_INTERFACE_H
#define __RAK_SERVER_INTERFACE_H
#include "NetworkTypes.h"
#include "PacketPriority.h"
#include "RakPeerInterface.h"
#include "BitStream.h"
#include "RakNetStatistics.h"
class RakServerInterface
{
public:
// Destructor
virtual ~RakServerInterface() {}
// AllowedPlayers : 한번에 동시 접속 가능한 클라이언트 수를 지정한다. 최대 65535 까지 가능하다.
// connectionValidationInteger : 예전에 사용했던 것으로 지금은 사용 하지 않는다.
// threadSleepTimer : 0 보다 작으면 싱글 쓰레드 이며 0 보다 크면 쓰레드가 잠시 멈추는 시간을 지정 한다. 일반적으로 30이 권장이고
// 0은 보통이고, -1은 아주 잠깐 동안을 뜻한다.
// port : 서버의 포트 번호.
// 리턴 값 : true 이면 초기화가 성공이고 false 이면 실패이다.
virtual bool Start(unsigned short AllowedPlayers, unsigned long connectionValidationInteger, int threadSleepTimer, unsigned short port)=0;
// 오프라인 상태에서 이 함수를 호출해야된다.
// SHA1, AES128, SYN Cookies, and RSA을 통한 보안 접속은 spoofing, replay attacks, data eavesdropping,
// packet tampering, and MitM attacks 을 막아낸다.
// 이것은 많은 프로세싱 처리와 작은 대역폭의 오버헤드를 일으킨다.
// privKeyE, privKeyN - private keys 는 RSACrypt class에서의 포인터 이다. 암호화 샘플을 참고해라.
// 만약 private keys가 0 이면 새로운 키는 이 함수를 호출하여 만들어진 것이야 한다.
virtual void InitializeSecurity(char *privKeyE, char *privKeyN)=0;
// 오프라인에서만 가능하다. 보안 기능을 정지시킨다.
virtual void DisableSecurity(void)=0;
// 클라이언트가 서버에 접속할 때 사용할 패스워드를 지정한다. 이 패스워드는 연결 할 때까지 지속한다.
// 패스워드가 없을 때는 0 이다. 언제라도 이 함수는 호출 가능하다.
virtual void SetPassword(char *_password)=0;
// 패스워드를 지정했다면 true, 아니라면 false를 반환한다.
virtual bool HasPassword(void)=0;
// 서버를 멈추어 데이터 동기화도 멈추고 모든 내부 데이터를 초기화 한다. 그리고 접속되어 있는 모든 플레이어와의 연결이 강제로 종료된다.
// 좀더 우아하게 연결을 끊을려고 한다면 먼저 정해진 방법으로 각 플레이어를 쫒아낸다.
// blockDuration : 아직 보내어야 될 데이터를 다 보낸 후 종료 할려면 소켓을 종료 할 때까지 기다릴 시간을 지정한다.
// 만약 0 이라면 데이터를 보냈는지와 상관없이 바로 종료 시켜버린다.
virtual void Disconnect(unsigned long blockDuration)=0;
// 이 함수는 서버가 활성화 상태 일 때에만 작동한다(즉 Start함수를 이용했을 경우). 실패하면 false, 성공하면 true를 반환한다.
// 데이터 스트림을 지정된 playerId에게 지정된 length 크기만큼 보낸다. 만약 UNASSIGNED_PLAYER_ID를 지정한면 모든 연결된 플레이어게 보낸다.
// 원한다면 중요도와 신뢰성을 HIGH_PRIORITY, RELIABLE, 0을 orderingChannel에 지정한다. Broadcast 을 true로 지정하면 모든 연결된 플레이어
// 에게 패킷을 보내는데 playerId 로 지정된 플레이어만 제외하고 보낸다. 만약 모든 플레이어에게 보낸다고 한다면 playerId를 UNASSIGNED_PLAYER_ID
// 로 지정한다.
virtual bool Send(char *data, const long length, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast)=0;
// 이 함수는 서버가 활성화 상태 일 때에만 작동한다(즉 Start함수를 이용했을 경우). 실패하면 false, 성공하면 true를 반환한다.
// 비트 스트림을 지정된 playerId에게 지정된 length 크기만큼 보낸다.
// 당신은 첫번째 바이트에 패킷을 고유상수를 설정하지만 당신이 TYPE_CHECKING 을 정의 하지 않기를 바라거나 내부적으로 체킹을 한다면
// 여분의 데이터를 추가하고 이 일은 하지 않게 한다. 만약 당신이 TYPE_CHECKING 을 설정했다면 당신은 BitStream::WriteBits 를 사용하여
// 타입 체킹을 피할 것이다. 이 인터페이스는 아마 다음 버전에서 수정될 것이다.
// 만약 UNASSIGNED_PLAYER_ID를 지정한면 모든 연결된 플레이어게 보낸다.
// 원한다면 중요도와 신뢰성을 HIGH_PRIORITY, RELIABLE, 0을 orderingChannel에 지정한다. Broadcast 을 true로 지정하면 모든 연결된 플레이어
// 에게 패킷을 보내는데 playerId 로 지정된 플레이어만 제외하고 보낸다. 만약 모든 플레이어에게 보낸다고 한다면 playerId를 UNASSIGNED_PLAYER_ID
// 로 지정한다.
virtual bool Send(RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast)=0;
// 패킷 큐에서 도착 한 패킷을 돌려준다. 뒤에 이것을 DeallocatePacket 패킷을 사용하여 해제해야 된다.
// CoreNetworkStructures.h 에서 패킷 구조체를 체크 하면 만약 0을 리턴하면 기다리고 있는 도중으로 패킷이 없음을 뜻한다.
// 만약 서버가 활성화 상태가 아니라면 언제나 0을 리턴하고, 서버가 연결이 끊어진다면 모든 기다리는 패킷이 날라간다. 패킷들은
// 모든 메모리 블록을 조합하여 메모리가 동기화 되도록 항상 업데이트 한다.
virtual Packet* Receive(void)=0;
// 지정된 플레이어를 쫒아낸다.
virtual void Kick(PlayerID playerId)=0;
// 받은 패킷을 처리하고 있다면 패킷을 해제한다.
virtual void DeallocatePacket(Packet *packet)=0;
// 접속가능한 클라이언트 수를 지정한다.
virtual void SetAllowedPlayers(unsigned short AllowedPlayers)=0;
// 접속 허용 가능한 클라이언트(플레이어)수를 반환한다.
virtual unsigned short GetAllowedPlayers(void) const=0;
// 현재 접속한 클라이언트 수를 반환한다/
virtual unsigned short GetConnectedPlayers(void)=0;
// 아이디를 통해 연결된 클라이언트의 IP를 스트링 포인트로 반환한다. 그리고로 항상 클라이언트의 포트도 반환한다.
virtual void GetPlayerIPFromID(PlayerID playerId, char returnValue[22], unsigned short *port)=0;
// 지정된 플레이어에게 핑을 보내어 요구한다.
virtual void PingPlayer(PlayerID playerId)=0;
// 지정된 클라이언트의 평균 핑 타임을 반환한다.
virtual int GetAveragePing(PlayerID playerId)=0;
// Returns the last ping time read for the specific player or -1 if none read yet
virtual int GetLastPing(PlayerID playerId)=0;
// Returns the lowest ping time read or -1 if none read yet
virtual int GetLowestPing(PlayerID playerId)=0;
// 핑을 자주 모든 플레이어에게 보낸다. 이것은 기본으로 적용된다. 만약 게임에서 자주 핑을 보내지 않을려고 하면 이 함수를 호출해라.
// 가끔씩 핑을 보내게 된다.
virtual void StartOccasionalPing(void)=0;
// 모든 플레이어에게 자주 핑을 보내는 것을 중단한다.
virtual void StopOccasionalPing(void)=0;
// 현재 서버가 활성화 상태라면 true를 반환 한다.
virtual bool IsActive(void) const=0;
// 클라이언트와 서버간의 랜덤수를 동기화 시키기 위한 시드값을 얻을 때 사용.
// 서버가 시작 후 StopSynchronizedRandomInteger 함수를 호출 하면 대역폭을 아낄 수 있다.
virtual unsigned long GetSynchronizedRandomInteger(void) const=0;
// 동기화된 랜던 정수 값을 시작 및 재시작 한다.
virtual void StartSynchronizedRandomInteger(void)=0;
// 동기화된 랜던 정수를 중단한다.
virtual void StopSynchronizedRandomInteger(void)=0;
/*
// Call this to automatically synchronize a block of memory.
// Unique identifier should be an integer corresponding to the same variable between clients and the server. This integer
// should start at 0 and not surpass the range of UniqueIDType. It is recommended you set this from an enum
// memoryBlock should point to the data you want to read from or write to with size of size in bytes
// isAuthority should be true if all other computers should match their data in memory block to yours. This is triggered by
// when the variable changes. So setting it to true on both the server and one client would make it so if the synchronized
// variable on that client changed, the server would then relay it to all clients.
// In the current implementation, setting isAuthority to true on the server will cause changes to that variable to be broadcast to
// all connected clients.
// synchronizationRules is an optional function pointer defined by you. It should
// return true if the two passed memory blocks are sufficiently different to synchronize them. This is an optimization so
// data that changes rapidly, such as per-frame, can be made to not update every frame
// The first parameter to synchronizationRules is the new data, the second is the internal copy of the old data
// secondaryUniqueIdentifier is optional and used when you have the same unique identifier and is intended for multiple instances of a class
// that derives from NetworkObject.
// You can call this anytime - however if you call it before the connection is complete initial data will not by synchronized
virtual void SynchronizeMemory(UniqueIDType uniqueIdentifier, char *memoryBlock, unsigned short size, bool isAuthority, bool (*synchronizationRules) (char*,char*)=0,ObjectID secondaryUniqueIdentifier=UNASSIGNED_OBJECT_ID)=0;
// Call this to stop synchronization of a block of memory previously defined by uniqueIdentifier and secondaryUniqueIdentifier
// by the call to SynchronizeMemory
// CALL THIS BEFORE SYNCHRONIZED MEMORY IS DEALLOCATED!
// It is not necessary to call this before disconnecting, as all synchronized states will be released then.
virtual void DesynchronizeMemory(UniqueIDType uniqueIdentifier, ObjectID secondaryUniqueIdentifier=UNASSIGNED_OBJECT_ID)=0;
// Call this to Desynchronize all synchronized memory
virtual void DesynchronizeAllMemory(void)=0;
*/
// This is an optional function to generate the compression layer from the input frequency table.
// You should call this twice - once with inputLayer as true and once as false.
// The frequency table passed here with inputLayer=true should match the frequency table on the recipient with inputLayer=false.
// Likewise, the frequency table passed here with inputLayer=false should match the frequency table on the recipient with inputLayer=true
// Calling this function when there is an existing layer will overwrite the old layer
// You should only call this when disconnected
// Return value: false (failure) if connected. Otherwise true (success)
virtual bool GenerateCompressionLayer(unsigned long inputFrequencyTable[256], bool inputLayer)=0;
// Delete the output or input layer as specified. This is not necessary to call and is only valuable for freeing memory
// You should only call this when disconnected
// Return value: false (failure) if connected. Otherwise true (success)
virtual bool DeleteCompressionLayer(bool inputLayer)=0;
// 일반적인 C 함수를 리모트 프로시저로 등록 한다.
// 클라이언트가 활성화 되었거나 그렇지 않을 때도 호출 가능하며, 등록된 함수는 제거도 가능하다.
virtual void RegisterAsRemoteProcedureCall(char* uniqueID, void (*functionName)(char *input, int numberOfBitsOfData, PlayerID sender))=0;
// RegisterAsRemoteProcedureCall로 등록한 C 함수를 등록 해제 한다.
virtual void UnregisterAsRemoteProcedureCall(char* uniqueID)=0;
// 클라이언트에 등록된 C 함수를 서버에서 호출 할 때 사용한다. 함수의 파라메터를 데이터로 보낼 수 있다.
// 일반적인 데이터나 비트스트림 으로도 보낼 수 있다. 지정된 playerId나 모든 클라이언트에게 보낼 수 있다. 만약 리턴 값을 받기를
// 원한다면 상대측에서 같은 방법으로 데이타를 보낸다. 반환 값이 true 이면 패킷이 제대로 보내진 것이고 false이면 잘 못되었다는
// 뜻이다. ubiqueID는 a-z 사이의 문자로 만들어져야 한다.
virtual bool RPC(char* uniqueID, char *data, unsigned long bitLength, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp)=0;
virtual bool RPC(char* uniqueID, RakNet::BitStream *parameters, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp)=0;
// OBSOLETE - DONE AUTOMATICALLY
// Handles an RPC packet. If you get a packet with the ID ID_RPC you should pass it to this function
// This is already done in Multiplayer.cpp, so if you use the Multiplayer class it is handled for you.
// Returns true on success, false on a bad packet or an unregistered function
// virtual bool HandleRPCPacket(Packet* packet)=0;
// Enables or disables frequency table tracking. This is required to get a frequency table, which is used to generate
// A new compression layer.
// You can call this at any time - however you SHOULD only call it when disconnected. Otherwise you will only track
// part of the values sent over the network.
// This value persists between connect calls and defaults to false (no frequency tracking)
virtual void SetTrackFrequencyTable(bool b)=0;
// Returns the frequency of outgoing bytes into outputFrequencyTable
// The purpose is to save to file as either a master frequency table from a sample game session for passing to
// GenerateCompressionLayer.
// You should only call this when disconnected
// Requires that you first enable data frequency tracking by calling SetTrackFrequencyTable(true)
// Return value: false (failure) if connected or if frequency table tracking is not enabled. Otherwise true (success)
virtual bool GetSendFrequencyTable(unsigned long outputFrequencyTable[256])=0;
// 압축율을 반환 한다. 작은 압축률이 좋다. 보내는 데이터의 압축이다.
virtual float GetCompressionRatio(void) const=0;
// 압축 해제율을 반환 한다. 높은 압축해제율이 좋다.
virtual float GetDecompressionRatio(void) const=0;
// 서버 내부적으로 지정된 메세지를 처음 접속하는 클라이언트에서 자동적으로 보낸다.
// This is useful to contain data such as the server name or message of the day. Access that struct with this
// function.
// *** NOTE ***
// If you change any data in the struct remote clients won't reflect this change unless you manually update them
// Do so by calling SendStaticServerDataToClient(UNASSIGNED_PLAYER_ID) (broadcast to all)
// The data is entered as an array and stored and returned as a BitStream.
// To store a bitstream, use the GetData() and GetNumberOfBytesUsed() methods
// of the bitstream for the 2nd and 3rd parameters
virtual RakNet::BitStream * GetStaticServerData(void)=0;
virtual void SetStaticServerData(char *data, const long length)=0;
// This sets to true or false whether we want to support relaying of static client data to other connected clients.
// If set to false it saves some bandwdith, however other clients won't know the static client data and attempting
// to read that data will return garbage. Default is true. This also only works for up to 32 players. Games
// supporting more than 32 players will have this shut off automatically upon server start and must have it forced
// back on with this function if you do indeed want it
// This should be called after the server is started in case you want to override when it shuts off at 32 players
virtual void SetRelayStaticClientData(bool b)=0;
// 지정된 플레이어에게만 static server data를 보낸다.
virtual void SendStaticServerDataToClient(PlayerID playerId)=0;
// Returns a pointer to an attached client's character name specified by the playerId
// Returns 0 if no such player is connected
// Note that you can modify the client data here. Changes won't be reflected on clients unless you force them to
// update by calling ChangeStaticClientData
// The server must be active for this to have meaning
// The data is entered as an array and stored and returned as a BitStream.
// Everytime you call GetStaticServerData it resets the read pointer to the start of the bitstream. To do multiple reads without reseting the pointer
// Maintain a pointer copy to the bitstream as in
// RakNet::BitStream *copy = ...->GetStaticServerData(...)=0;
// To store a bitstream, use the GetData() and GetNumberOfBytesUsed() methods
// of the bitstream for the 2nd and 3rd parameters
// Note that the client may change at any time the
// data contents and/or its length!
virtual RakNet::BitStream * GetStaticClientData(PlayerID playerId)=0;
virtual void SetStaticClientData(PlayerID playerId, char *data, const long length)=0;
// This function is used to update the information on connected clients when the server effects a change
// of static client data
// playerChangedId should be the playerId of the player whose data was changed. This is the parameter passed to
// GetStaticClientData to get a pointer to that player's information
// Note that a client that gets this new information for himself will update the data for his playerID but not his local data (which is the user's copy)
// i.e. player 5 would have the data returned by GetStaticClientData(5) changed but his local information returned by
// GetStaticClientData(UNASSIGNED_PLAYER_ID) would remain the same as it was previously.
// playerToSendToId should be the player you want to update with the new information. This will almost always
// be everybody, in which case you should pass UNASSIGNED_PLAYER_ID.
// The server must be active for this to have meaning
virtual void ChangeStaticClientData(PlayerID playerChangedId, PlayerID playerToSendToId)=0;
// Internally store the IP address(es) for the server and return how many it has.
// This can easily be more than one, for example a system on both a LAN and with a net connection.
// The server does not have to be active for this to work
virtual unsigned int GetNumberOfAddresses(void)=0;
// Call this function where 0 <= index < x where x is the value returned by GetNumberOfAddresses
// Returns a static string filled with the server IP of the specified index
// Strings returned in no particular order. You'll have to check every index see which string you want
// Returns 0 on invalid input
// The server does not have to be active for this to work
virtual const char* GetLocalIP(unsigned int index)=0;
// 패킷을 패킷 리시브 큐의 제일 끝 부분에 밀어 넣는다.
virtual void PushBackPacket(Packet *packet)=0;
// playerID의 인덱스를 반환한다.
virtual int GetIndexFromPlayerID(PlayerID playerId)=0;
// 모든 playerid를 순환하여 조사하여 0과 최대 숫자 사이에서의 인덱스 값으로 playerId를 반환한다.
virtual PlayerID GetPlayerIDFromIndex(int index)=0;
// 지정된 IP를 접속 금지 리스트에 추가한다.
virtual void AddToBanList(const char *IP)=0;
// 지정된 IP를 접속 금지 리스트에서 제거 한다.
virtual void RemoveFromBanList(const char *IP)=0;
// 접속 금지 IP 리스트를 모두 삭제 한다.
virtual void ClearBanList(void)=0;
// 지정된 IP가 접속 금지로 지정되었다면 true를 반환 한다.
virtual bool IsBanned(const char *IP)=0;
// playerID를 사용 중이면 true를 반환 한다.
virtual bool IsActivePlayerID(PlayerID playerId)=0;
// Change the MTU size in order to improve performance when sending large packets
// This can only be called when not connected.
// Returns false on failure (we are connected). True on success. Maximum allowed size is MAXIMUM_MTU_SIZE
// A too high of value will cause packets not to arrive at worst and be fragmented at best.
// A too low of value will split packets unnecessarily.
// Set according to the following table:
// 1500. The largest Ethernet packet size=0; it is also the default value.
// This is the typical setting for non-PPPoE, non-VPN connections. The default value for NETGEAR routers, adapters and switches.
// 1492. The size PPPoE prefers.
// 1472. Maximum size to use for pinging. (Bigger packets are fragmented.)
// 1468. The size DHCP prefers.
// 1460. Usable by AOL if you don't have large email attachments, etc.
// 1430. The size VPN and PPTP prefer.
// 1400. Maximum size for AOL DSL.
// 576. Typical value to connect to dial-up ISPs. (Default)
virtual bool SetMTUSize(int size)=0;
// MTU의 크기를 반환한다.
virtual int GetMTUSize(void) const=0;
// Description:
// Returns a structure containing a large set of network statistics for the specified system
// You can map this data to a string using the C style StatisticsToString function
//
// Parameters
// playerId: Which connected system to get statistics for
//
// Returns:
// 0 on can't find the specified system. A pointer to a set of data otherwise.
virtual RakNetStatisticsStruct * const GetStatistics(PlayerID playerId)=0;
};
#endif