mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-13 03:28:19 +00:00
Add checkpoints. Client undestand that it is a DDRace server fully. Need to rework /top5 /rank. Clean rubbish. I want to sleep(
This commit is contained in:
parent
cf63f18954
commit
6fabca9e10
|
@ -574,6 +574,17 @@ int CCollision::IsCp(int x, int y)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CCollision::IsCheckpoint(int Index)
|
||||||
|
{
|
||||||
|
if(Index < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int z = m_pTiles[Index].m_Index;
|
||||||
|
if(z >= 35 && z <= 59)
|
||||||
|
return z-35;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
vec2 CCollision::CpSpeed(int Index)
|
vec2 CCollision::CpSpeed(int Index)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@ public:
|
||||||
int IsThrough(int x, int y);
|
int IsThrough(int x, int y);
|
||||||
int IsNoLaser(int x, int y);
|
int IsNoLaser(int x, int y);
|
||||||
int IsFNoLaser(int x, int y);
|
int IsFNoLaser(int x, int y);
|
||||||
|
|
||||||
|
int IsCheckpoint(int Index);
|
||||||
|
|
||||||
int IsCp(int x, int y);
|
int IsCp(int x, int y);
|
||||||
|
|
||||||
vec2 CpSpeed(int index);
|
vec2 CpSpeed(int index);
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <engine/shared/config.h>
|
#include <engine/shared/config.h>
|
||||||
#include <engine/server/server.h>
|
#include <engine/server/server.h>
|
||||||
#include <game/server/gamecontext.h>
|
#include <game/server/gamecontext.h>
|
||||||
#include <game/mapitems.h>
|
#include <game/mapitems.h>
|
||||||
#include <game/server/gamemodes/DDRace.h>
|
#include <game/server/gamemodes/DDRace.h>
|
||||||
|
|
||||||
|
#include <game/server/score.h>
|
||||||
|
|
||||||
#include "character.h"
|
#include "character.h"
|
||||||
#include "laser.h"
|
#include "laser.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
@ -591,50 +595,142 @@ void CCharacter::Tick()
|
||||||
//DDRace
|
//DDRace
|
||||||
char aBuftime[128];
|
char aBuftime[128];
|
||||||
float time = (float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed());
|
float time = (float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed());
|
||||||
int z = GameServer()->Collision()->IsTeleport(m_Pos.x, m_Pos.y);
|
CPlayerData *pData = GameServer()->Score()->PlayerData(m_pPlayer->GetCID());
|
||||||
|
|
||||||
if(Server()->Tick() - m_RefreshTime >= Server()->TickSpeed())
|
if(Server()->Tick() - m_RefreshTime >= Server()->TickSpeed())
|
||||||
{
|
{
|
||||||
//GameServer()->SendBroadcast("FIRST_IF", m_pPlayer->GetCID());
|
|
||||||
if (m_RaceState == RACE_STARTED) {
|
if (m_RaceState == RACE_STARTED) {
|
||||||
//GameServer()->SendBroadcast("SECOND_IF", m_pPlayer->GetCID());
|
int IntTime = (int)time;
|
||||||
int int_time = (int)time;
|
if(m_pPlayer->m_IsUsingRaceClient)
|
||||||
str_format(aBuftime, sizeof(aBuftime), "%d m %d s\n%s", int_time/60,(int_time%60), ( g_Config.m_SvBroadcast[0] == 0) ? "" : g_Config.m_SvBroadcast);
|
{
|
||||||
GameServer()->SendBroadcast(aBuftime, m_pPlayer->GetCID());
|
CNetMsg_Sv_RaceTime Msg;
|
||||||
|
Msg.m_Time = IntTime;
|
||||||
|
Msg.m_Check = 0;
|
||||||
|
|
||||||
|
if(m_CpActive != -1 && m_CpTick > Server()->Tick())
|
||||||
|
{
|
||||||
|
if(pData->m_BestTime && pData->m_aBestCpTime[m_CpActive] != 0)
|
||||||
|
{
|
||||||
|
float Diff = (m_CpCurrent[m_CpActive] - pData->m_aBestCpTime[m_CpActive])*100;
|
||||||
|
Msg.m_Check = (int)Diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID());
|
||||||
|
} else {
|
||||||
|
str_format(aBuftime, sizeof(aBuftime), "Current Time: %d min %d sec", IntTime/60, IntTime%60);
|
||||||
|
|
||||||
|
if(m_CpActive != -1 && m_CpTick > Server()->Tick())
|
||||||
|
{
|
||||||
|
if(pData->m_BestTime && pData->m_aBestCpTime[m_CpActive] != 0)
|
||||||
|
{
|
||||||
|
char aTmp[128];
|
||||||
|
float Diff = m_CpCurrent[m_CpActive] - pData->m_aBestCpTime[m_CpActive];
|
||||||
|
str_format(aTmp, sizeof(aTmp), "\nCheckpoint | Diff : %+5.2f", Diff);
|
||||||
|
strcat(aBuftime, aTmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( g_Config.m_SvBroadcast[0] != 0) {
|
||||||
|
char aTmp[128];
|
||||||
|
str_format(aTmp, sizeof(aTmp), "\n%s\n", g_Config.m_SvBroadcast);
|
||||||
|
strcat(aBuftime, aTmp);
|
||||||
|
}
|
||||||
|
GameServer()->SendBroadcast(aBuftime, m_pPlayer->GetCID());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (g_Config.m_SvBroadcast[0] != 0)
|
if( g_Config.m_SvBroadcast[0] != 0) {
|
||||||
|
char aTmp[128];
|
||||||
|
str_format(aTmp, sizeof(aTmp), "%s\n", g_Config.m_SvBroadcast);
|
||||||
|
strcat(aBuftime, aTmp);
|
||||||
GameServer()->SendBroadcast(g_Config.m_SvBroadcast, m_pPlayer->GetCID());
|
GameServer()->SendBroadcast(g_Config.m_SvBroadcast, m_pPlayer->GetCID());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
m_RefreshTime = Server()->Tick();
|
m_RefreshTime = Server()->Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cp = GameServer()->Collision()->IsCheckpoint(MapIndex);
|
||||||
|
if(cp != -1 && m_RaceState == RACE_STARTED)
|
||||||
|
{
|
||||||
|
m_CpActive = cp;
|
||||||
|
m_CpCurrent[cp] = time;
|
||||||
|
m_CpTick = Server()->Tick() + Server()->TickSpeed()*2;
|
||||||
|
}
|
||||||
if(((TileIndex1 == TILE_BEGIN) || (TileIndex2 == TILE_BEGIN)) && (m_RaceState == RACE_NONE || m_RaceState == RACE_STARTED))
|
if(((TileIndex1 == TILE_BEGIN) || (TileIndex2 == TILE_BEGIN)) && (m_RaceState == RACE_NONE || m_RaceState == RACE_STARTED))
|
||||||
{
|
{
|
||||||
m_StartTime = Server()->Tick();
|
m_StartTime = Server()->Tick();
|
||||||
m_RefreshTime = Server()->Tick();
|
m_RefreshTime = Server()->Tick();
|
||||||
m_RaceState = RACE_STARTED;
|
m_RaceState = RACE_STARTED;
|
||||||
}
|
}
|
||||||
|
int z = GameServer()->Collision()->IsTeleport(m_Pos.x, m_Pos.y);
|
||||||
if(((TileIndex1 == TILE_END) || (TileIndex2 == TILE_END)) && m_RaceState == RACE_STARTED)
|
if(((TileIndex1 == TILE_END) || (TileIndex2 == TILE_END)) && m_RaceState == RACE_STARTED)
|
||||||
{
|
{
|
||||||
char aBuf[128];
|
char aBuf[128];
|
||||||
if ((int)time / 60 != 0)
|
str_format(aBuf, sizeof(aBuf), "%s finished in: %d minute(s) %5.2f second(s)", Server()->ClientName(m_pPlayer->GetCID()), (int)time/60, time-((int)time/60*60));
|
||||||
str_format(aBuf, sizeof(aBuf), "%s finished in: %d minute(s) %5.3f second(s)", (!g_Config.m_SvHideScore)?Server()->ClientName(m_pPlayer->GetCID()):"You", (int)time/60, time - ((int)time/60*60));
|
if(!g_Config.m_SvHideScore)
|
||||||
else
|
|
||||||
str_format(aBuf, sizeof(aBuf), "%s finished in: %5.3f second(s)", (!g_Config.m_SvHideScore) ? Server()->ClientName(m_pPlayer->GetCID()):"You", time - ((int)time/60*60));
|
|
||||||
if (!g_Config.m_SvHideScore)
|
|
||||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
|
||||||
else
|
|
||||||
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
|
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
|
||||||
CPlayerScore *pPScore = ((CGameControllerDDRace*) GameServer()->m_pController)->m_Score.SearchName(Server()->ClientName(m_pPlayer->GetCID()));
|
else
|
||||||
if(pPScore && time - pPScore->m_Score < 0)
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
||||||
|
|
||||||
|
if(time - pData->m_BestTime < 0)
|
||||||
{
|
{
|
||||||
str_format(aBuf, sizeof(aBuf), "New record: %5.3f second(s) better", time - pPScore->m_Score);
|
// new record \o/
|
||||||
if (!g_Config.m_SvHideScore)
|
str_format(aBuf, sizeof(aBuf), "New record: %5.2f second(s) better", time - pData->m_BestTime);
|
||||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
if(!g_Config.m_SvHideScore)
|
||||||
else
|
|
||||||
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
|
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
|
||||||
|
else
|
||||||
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!pData->m_BestTime || time < pData->m_BestTime)
|
||||||
|
{
|
||||||
|
// update the score
|
||||||
|
pData->Set(time, m_CpCurrent);
|
||||||
|
|
||||||
|
if(str_comp_num(Server()->ClientName(m_pPlayer->GetCID()), "nameless tee", 12) != 0)
|
||||||
|
GameServer()->Score()->SaveScore(m_pPlayer->GetCID(), time, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update server best time
|
||||||
|
if(!GameServer()->m_pController->m_CurrentRecord || time < GameServer()->m_pController->m_CurrentRecord)
|
||||||
|
{
|
||||||
|
// check for nameless
|
||||||
|
if(str_comp_num(Server()->ClientName(m_pPlayer->GetCID()), "nameless tee", 12) != 0)
|
||||||
|
GameServer()->m_pController->m_CurrentRecord = time;
|
||||||
|
}
|
||||||
|
|
||||||
m_RaceState = RACE_NONE;
|
m_RaceState = RACE_NONE;
|
||||||
if(strncmp(Server()->ClientName(m_pPlayer->GetCID()), "nameless tee", 12) != 0)
|
// set player score
|
||||||
((CGameControllerDDRace*)GameServer()->m_pController)->m_Score.ParsePlayer(Server()->ClientName(m_pPlayer->GetCID()), (float)time);
|
if(!GameServer()->Score()->PlayerData(m_pPlayer->GetCID())->m_CurrentTime || GameServer()->Score()->PlayerData(m_pPlayer->GetCID())->m_CurrentTime > time)
|
||||||
|
{
|
||||||
|
GameServer()->Score()->PlayerData(m_pPlayer->GetCID())->m_CurrentTime = time;
|
||||||
|
|
||||||
|
// send it to all players
|
||||||
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
{
|
||||||
|
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_IsUsingRaceClient)
|
||||||
|
{
|
||||||
|
if(g_Config.m_SvHideScore || i == m_pPlayer->GetCID())
|
||||||
|
{
|
||||||
|
CNetMsg_Sv_PlayerTime Msg;
|
||||||
|
char aBuf[16];
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%.0f", time*100.0f); // damn ugly but the only way i know to do it
|
||||||
|
int TimeToSend;
|
||||||
|
sscanf(aBuf, "%d", &TimeToSend);
|
||||||
|
Msg.m_Time = TimeToSend;
|
||||||
|
Msg.m_Cid = m_pPlayer->GetCID();
|
||||||
|
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int TTime = 0-(int)time;
|
||||||
|
if(m_pPlayer->m_Score < TTime)
|
||||||
|
m_pPlayer->m_Score = TTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
if(((TileIndex1 == TILE_FREEZE) || (TileIndex2 == TILE_FREEZE)) && !m_Super)
|
if(((TileIndex1 == TILE_FREEZE) || (TileIndex2 == TILE_FREEZE)) && !m_Super)
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,7 +167,7 @@ public:
|
||||||
// checkpoints
|
// checkpoints
|
||||||
int m_CpTick;
|
int m_CpTick;
|
||||||
int m_CpActive;
|
int m_CpActive;
|
||||||
float m_CpCurrent[149];
|
float m_CpCurrent[25];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <base/math.h>
|
#include <base/math.h>
|
||||||
#include <engine/shared/config.h>
|
#include <engine/shared/config.h>
|
||||||
|
@ -11,6 +12,9 @@
|
||||||
#include <game/gamecore.h>
|
#include <game/gamecore.h>
|
||||||
#include "gamemodes/DDRace.h"
|
#include "gamemodes/DDRace.h"
|
||||||
|
|
||||||
|
#include "score.h"
|
||||||
|
#include "score/file_score.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
RESET,
|
RESET,
|
||||||
|
@ -32,7 +36,7 @@ void CGameContext::Construct(int Resetting)
|
||||||
|
|
||||||
if(Resetting==NO_RESET)
|
if(Resetting==NO_RESET)
|
||||||
m_pVoteOptionHeap = new CHeap();
|
m_pVoteOptionHeap = new CHeap();
|
||||||
//m_Cheats = g_Config.m_SvCheats;
|
m_pScore = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameContext::CGameContext(int Resetting)
|
CGameContext::CGameContext(int Resetting)
|
||||||
|
@ -705,7 +709,7 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
||||||
str_format(buf, sizeof(buf), "/Info /Credits %s",g_Config.m_SvPauseable?"/pause":"");
|
str_format(buf, sizeof(buf), "/Info /Credits %s",g_Config.m_SvPauseable?"/pause":"");
|
||||||
SendChatTarget(ClientId, buf);
|
SendChatTarget(ClientId, buf);
|
||||||
SendChatTarget(ClientId, "/rank /top5 /top5 5 or any number");
|
SendChatTarget(ClientId, "/rank /top5 /top5 5 or any number");
|
||||||
}
|
}/*
|
||||||
else if(!strncmp(pMsg->m_pMessage, "/top5", 5) && !g_Config.m_SvHideScore)
|
else if(!strncmp(pMsg->m_pMessage, "/top5", 5) && !g_Config.m_SvHideScore)
|
||||||
{
|
{
|
||||||
const char *pt = pMsg->m_pMessage;
|
const char *pt = pMsg->m_pMessage;
|
||||||
|
@ -751,7 +755,7 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
||||||
str_format(buf, sizeof(buf), "%s is not ranked", Server()->ClientName(ClientId));
|
str_format(buf, sizeof(buf), "%s is not ranked", Server()->ClientName(ClientId));
|
||||||
|
|
||||||
SendChatTarget(ClientId, buf);
|
SendChatTarget(ClientId, buf);
|
||||||
}
|
} finish this later */
|
||||||
else if (!str_comp_nocase(pMsg->m_pMessage, "/emotepain")&&g_Config.m_SvEmotionalTees)
|
else if (!str_comp_nocase(pMsg->m_pMessage, "/emotepain")&&g_Config.m_SvEmotionalTees)
|
||||||
{
|
{
|
||||||
CCharacter* pChr = p->GetCharacter();
|
CCharacter* pChr = p->GetCharacter();
|
||||||
|
@ -853,6 +857,25 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(MsgId == NETMSGTYPE_CL_ISRACE)
|
||||||
|
{
|
||||||
|
p->m_IsUsingRaceClient = true;
|
||||||
|
// send time of all players
|
||||||
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
{
|
||||||
|
if(m_apPlayers[i] && Score()->PlayerData(i)->m_CurrentTime > 0)
|
||||||
|
{
|
||||||
|
char aBuf[16];
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%.0f", Score()->PlayerData(i)->m_CurrentTime*100.0f); // damn ugly but the only way i know to do it
|
||||||
|
int TimeToSend;
|
||||||
|
sscanf(aBuf, "%d", &TimeToSend);
|
||||||
|
CNetMsg_Sv_PlayerTime Msg;
|
||||||
|
Msg.m_Time = TimeToSend;
|
||||||
|
Msg.m_Cid = i;
|
||||||
|
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(MsgId == NETMSGTYPE_CL_CALLVOTE)
|
else if(MsgId == NETMSGTYPE_CL_CALLVOTE)
|
||||||
{
|
{
|
||||||
|
@ -1134,6 +1157,7 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
||||||
pChr->m_EmoteStop = Server()->Tick() + 2 * Server()->TickSpeed();
|
pChr->m_EmoteStop = Server()->Tick() + 2 * Server()->TickSpeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (MsgId == NETMSGTYPE_CL_KILL && !m_World.m_Paused)
|
else if (MsgId == NETMSGTYPE_CL_KILL && !m_World.m_Paused)
|
||||||
{
|
{
|
||||||
if(p->m_Last_Kill && p->m_Last_Kill+Server()->TickSpeed()*3 > Server()->Tick())
|
if(p->m_Last_Kill && p->m_Last_Kill+Server()->TickSpeed()*3 > Server()->Tick())
|
||||||
|
@ -1738,6 +1762,16 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
|
||||||
|
|
||||||
Server()->SetBrowseInfo(m_pController->m_pGameType, -1);
|
Server()->SetBrowseInfo(m_pController->m_pGameType, -1);
|
||||||
|
|
||||||
|
|
||||||
|
// delete old score object
|
||||||
|
if(m_pScore)
|
||||||
|
delete m_pScore;
|
||||||
|
|
||||||
|
// create score object (add sql later)
|
||||||
|
//if(g_Config.m_SvUseSQL)
|
||||||
|
// m_pScore = new CSqlScore(this);
|
||||||
|
//else
|
||||||
|
m_pScore = new CFileScore(this);
|
||||||
// setup core world
|
// setup core world
|
||||||
//for(int i = 0; i < MAX_CLIENTS; i++)
|
//for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
// game.players[i].core.world = &game.world.core;
|
// game.players[i].core.world = &game.world.core;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "gamecontroller.h"
|
#include "gamecontroller.h"
|
||||||
#include "gameworld.h"
|
#include "gameworld.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tick
|
Tick
|
||||||
|
@ -41,6 +42,7 @@ class CGameContext : public IGameServer
|
||||||
CCollision m_Collision;
|
CCollision m_Collision;
|
||||||
CNetObjHandler m_NetObjHandler;
|
CNetObjHandler m_NetObjHandler;
|
||||||
CTuningParams m_Tuning;
|
CTuningParams m_Tuning;
|
||||||
|
class IScore *m_pScore;
|
||||||
|
|
||||||
static void ConMute(IConsole::IResult *pResult, void *pUserData, int cid);
|
static void ConMute(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||||
static void ConSetlvl(IConsole::IResult *pResult, void *pUserData, int cid);
|
static void ConSetlvl(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||||
|
@ -97,6 +99,8 @@ public:
|
||||||
class IConsole *Console() { return m_pConsole; }
|
class IConsole *Console() { return m_pConsole; }
|
||||||
CCollision *Collision() { return &m_Collision; }
|
CCollision *Collision() { return &m_Collision; }
|
||||||
CTuningParams *Tuning() { return &m_Tuning; }
|
CTuningParams *Tuning() { return &m_Tuning; }
|
||||||
|
|
||||||
|
class IScore *Score() { return m_pScore; }
|
||||||
|
|
||||||
CGameContext();
|
CGameContext();
|
||||||
~CGameContext();
|
~CGameContext();
|
||||||
|
|
|
@ -46,6 +46,7 @@ protected:
|
||||||
|
|
||||||
char m_aMapWish[128];
|
char m_aMapWish[128];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int m_RoundStartTick;
|
int m_RoundStartTick;
|
||||||
int m_GameOverTick;
|
int m_GameOverTick;
|
||||||
|
@ -63,6 +64,8 @@ protected:
|
||||||
public:
|
public:
|
||||||
const char *m_pGameType;
|
const char *m_pGameType;
|
||||||
|
|
||||||
|
float m_CurrentRecord;
|
||||||
|
|
||||||
//bool IsTeamplay() const;
|
//bool IsTeamplay() const;
|
||||||
|
|
||||||
IGameController(class CGameContext *pGameServer);
|
IGameController(class CGameContext *pGameServer);
|
||||||
|
|
|
@ -15,7 +15,6 @@ public:
|
||||||
vec2 *m_pTeleporter;
|
vec2 *m_pTeleporter;
|
||||||
|
|
||||||
void InitTeleporter();
|
void InitTeleporter();
|
||||||
CScore m_Score;
|
|
||||||
|
|
||||||
virtual void Tick();
|
virtual void Tick();
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,6 @@ CPlayer::CPlayer(CGameContext *pGameServer, int CID, int Team)
|
||||||
m_DieTick = Server()->Tick();
|
m_DieTick = Server()->Tick();
|
||||||
m_ScoreStartTick = Server()->Tick();
|
m_ScoreStartTick = Server()->Tick();
|
||||||
Character = 0;
|
Character = 0;
|
||||||
m_CharacterCopy = 0;
|
|
||||||
m_Muted = 0;
|
m_Muted = 0;
|
||||||
this->m_ClientID = CID;
|
this->m_ClientID = CID;
|
||||||
m_Team = GameServer()->m_pController->ClampTeam(Team);
|
m_Team = GameServer()->m_pController->ClampTeam(Team);
|
||||||
|
@ -32,6 +31,11 @@ CPlayer::CPlayer(CGameContext *pGameServer, int CID, int Team)
|
||||||
m_SentAfkWarning2 = 0;
|
m_SentAfkWarning2 = 0;
|
||||||
|
|
||||||
m_PauseInfo.m_Respawn = false;
|
m_PauseInfo.m_Respawn = false;
|
||||||
|
|
||||||
|
m_IsUsingRaceClient = false;
|
||||||
|
m_LastSentTime = 0;
|
||||||
|
|
||||||
|
GameServer()->Score()->PlayerData(CID)->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlayer::~CPlayer()
|
CPlayer::~CPlayer()
|
||||||
|
@ -42,17 +46,6 @@ CPlayer::~CPlayer()
|
||||||
|
|
||||||
void CPlayer::Tick()
|
void CPlayer::Tick()
|
||||||
{
|
{
|
||||||
int pos=0;
|
|
||||||
CPlayerScore *pscore = ((CGameControllerDDRace*)GameServer()->m_pController)->m_Score.SearchName(Server()->ClientName(m_ClientID), pos);
|
|
||||||
if(pscore && pos > -1 && pscore->m_Score != -1)
|
|
||||||
{
|
|
||||||
float time = pscore->m_Score;
|
|
||||||
//if (!config.sv_hide_score)
|
|
||||||
m_Score = time * 100;
|
|
||||||
//else
|
|
||||||
// score=authed;
|
|
||||||
} else
|
|
||||||
m_Score = 0.0f;
|
|
||||||
Server()->SetClientAuthed(m_ClientID, m_Authed);
|
Server()->SetClientAuthed(m_ClientID, m_Authed);
|
||||||
Server()->SetClientScore(m_ClientID, m_Score);
|
Server()->SetClientScore(m_ClientID, m_Score);
|
||||||
|
|
||||||
|
@ -95,6 +88,23 @@ void CPlayer::Tick()
|
||||||
}
|
}
|
||||||
else if(m_Spawning && m_RespawnTick <= Server()->Tick())
|
else if(m_Spawning && m_RespawnTick <= Server()->Tick())
|
||||||
TryRespawn();
|
TryRespawn();
|
||||||
|
|
||||||
|
// send best time
|
||||||
|
if(m_IsUsingRaceClient)
|
||||||
|
{
|
||||||
|
if(m_LastSentTime > GameServer()->m_pController->m_CurrentRecord || (!m_LastSentTime && GameServer()->m_pController->m_CurrentRecord))
|
||||||
|
{
|
||||||
|
char aBuf[16];
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%.0f", GameServer()->m_pController->m_CurrentRecord*100.0f); // damn ugly but the only way i know to do it
|
||||||
|
int TimeToSend;
|
||||||
|
sscanf(aBuf, "%d", &TimeToSend);
|
||||||
|
CNetMsg_Sv_Record Msg;
|
||||||
|
Msg.m_Time = TimeToSend;
|
||||||
|
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_ClientID);
|
||||||
|
|
||||||
|
m_LastSentTime = GameServer()->m_pController->m_CurrentRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayer::Snap(int SnappingClient)
|
void CPlayer::Snap(int SnappingClient)
|
||||||
|
@ -112,11 +122,18 @@ void CPlayer::Snap(int SnappingClient)
|
||||||
Info->m_LatencyFlux = m_Latency.m_Max-m_Latency.m_Min;
|
Info->m_LatencyFlux = m_Latency.m_Max-m_Latency.m_Min;
|
||||||
Info->m_Local = 0;
|
Info->m_Local = 0;
|
||||||
Info->m_ClientId = m_ClientID;
|
Info->m_ClientId = m_ClientID;
|
||||||
Info->m_Score = m_Score;
|
|
||||||
Info->m_Team = m_Team;
|
|
||||||
|
|
||||||
if(m_ClientID == SnappingClient)
|
if(m_ClientID == SnappingClient)
|
||||||
Info->m_Local = 1;
|
Info->m_Local = 1;
|
||||||
|
|
||||||
|
// send 0 if times of otheres are not shown
|
||||||
|
if(SnappingClient != m_ClientID)
|
||||||
|
Info->m_Score = 0;
|
||||||
|
else
|
||||||
|
Info->m_Score = m_Score;
|
||||||
|
|
||||||
|
Info->m_Team = m_Team;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayer::OnDisconnect()
|
void CPlayer::OnDisconnect()
|
||||||
|
|
|
@ -32,7 +32,6 @@ public:
|
||||||
void KillCharacter(int Weapon = WEAPON_GAME);
|
void KillCharacter(int Weapon = WEAPON_GAME);
|
||||||
CCharacter *GetCharacter();
|
CCharacter *GetCharacter();
|
||||||
|
|
||||||
CCharacter* m_CharacterCopy;
|
|
||||||
struct PauseInfo {
|
struct PauseInfo {
|
||||||
CCharacterCore m_Core;
|
CCharacterCore m_Core;
|
||||||
int m_StartTime;
|
int m_StartTime;
|
||||||
|
@ -112,6 +111,14 @@ public:
|
||||||
int m_ScoreStartTick;
|
int m_ScoreStartTick;
|
||||||
bool m_ForceBalanced;
|
bool m_ForceBalanced;
|
||||||
|
|
||||||
|
float m_BestTime;
|
||||||
|
float m_aBestCpTime[25];
|
||||||
|
|
||||||
|
bool m_ResetPickups;
|
||||||
|
|
||||||
|
bool m_IsUsingRaceClient;
|
||||||
|
float m_LastSentTime;
|
||||||
|
|
||||||
// afk timer
|
// afk timer
|
||||||
void AfkTimer(int new_target_x, int new_target_y);
|
void AfkTimer(int new_target_x, int new_target_y);
|
||||||
int64 m_LastPlaytime;
|
int64 m_LastPlaytime;
|
||||||
|
|
|
@ -1,38 +1,53 @@
|
||||||
/* copyright (c) 2008 rajh and gregwar. Score stuff */
|
#ifndef GAME_SERVER_INTERFACE_SCORE_H
|
||||||
|
#define GAME_SERVER_INTERFACE_SCORE_H
|
||||||
|
|
||||||
#ifndef SCORE_H_RACE
|
#include "entities/character.h"
|
||||||
#define SCORE_H_RACE
|
#include "gamecontext.h"
|
||||||
#include <engine/server.h>
|
|
||||||
#include <engine/shared/protocol.h>
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
|
#define NUM_TELEPORT 25
|
||||||
|
|
||||||
class CPlayerScore
|
class CPlayerData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
char name[MAX_NAME_LENGTH];
|
CPlayerData()
|
||||||
float m_Score;
|
{
|
||||||
|
Reset();
|
||||||
CPlayerScore(const char *name, float score);
|
}
|
||||||
|
|
||||||
bool operator==(const CPlayerScore& other) { return (this->m_Score == other.m_Score); }
|
void Reset()
|
||||||
bool operator<(const CPlayerScore& other) { return (this->m_Score < other.m_Score); }
|
{
|
||||||
|
m_BestTime = 0;
|
||||||
|
m_CurrentTime = 0;
|
||||||
|
for(int i = 0; i < NUM_TELEPORT; i++)
|
||||||
|
m_aBestCpTime[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(float Time, float CpTime[NUM_TELEPORT])
|
||||||
|
{
|
||||||
|
m_BestTime = Time;
|
||||||
|
for(int i = 0; i < NUM_TELEPORT; i++)
|
||||||
|
m_aBestCpTime[i] = CpTime[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
float m_BestTime;
|
||||||
|
float m_CurrentTime;
|
||||||
|
float m_aBestCpTime[NUM_TELEPORT];
|
||||||
};
|
};
|
||||||
|
|
||||||
class CScore
|
class IScore
|
||||||
{
|
{
|
||||||
class CGameContext *m_pGameServer;
|
CPlayerData m_aPlayerData[MAX_CLIENTS];
|
||||||
std::string SaveFile();
|
|
||||||
public:
|
public:
|
||||||
CScore(class CGameContext *pGameServer);
|
virtual ~IScore() {}
|
||||||
CScore();
|
|
||||||
void Save();
|
CPlayerData *PlayerData(int ID) { return &m_aPlayerData[ID]; }
|
||||||
void Load();
|
|
||||||
CPlayerScore *SearchName(const char *name, int &pos);
|
virtual void LoadScore(int ClientID) = 0;
|
||||||
CPlayerScore *SearchName(const char *name);
|
virtual void SaveScore(int ClientID, float Time, CCharacter *pChar) = 0;
|
||||||
void ParsePlayer(const char *name, float score);
|
|
||||||
std::list<std::string> Top5Draw(int id, int debut);
|
virtual void ShowTop5(int ClientID, int Debut=1) = 0;
|
||||||
|
virtual void ShowRank(int ClientID, const char* pName, bool Search=false) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
273
src/game/server/score/file_score.cpp
Normal file
273
src/game/server/score/file_score.cpp
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
/* copyright (c) 2008 rajh and gregwar. Score stuff */
|
||||||
|
|
||||||
|
#include <engine/shared/config.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../gamemodes/DDRace.h"
|
||||||
|
#include "file_score.h"
|
||||||
|
|
||||||
|
static LOCK gs_ScoreLock = 0;
|
||||||
|
|
||||||
|
CFileScore::CPlayerScore::CPlayerScore(const char *pName, float Score, const char *pIP, float aCpTime[NUM_TELEPORT])
|
||||||
|
{
|
||||||
|
str_copy(m_aName, pName, sizeof(m_aName));
|
||||||
|
m_Score = Score;
|
||||||
|
str_copy(m_aIP, pIP, sizeof(m_aIP));
|
||||||
|
for(int i = 0; i < NUM_TELEPORT; i++)
|
||||||
|
m_aCpTime[i] = aCpTime[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileScore::CFileScore(CGameContext *pGameServer) : m_pGameServer(pGameServer), m_pServer(pGameServer->Server())
|
||||||
|
{
|
||||||
|
if(gs_ScoreLock == 0)
|
||||||
|
gs_ScoreLock = lock_create();
|
||||||
|
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileScore::~CFileScore()
|
||||||
|
{
|
||||||
|
lock_wait(gs_ScoreLock);
|
||||||
|
|
||||||
|
// clear list
|
||||||
|
m_Top.clear();
|
||||||
|
|
||||||
|
lock_release(gs_ScoreLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SaveFile()
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
//if(g_Config.m_SvScoreFolder[0])
|
||||||
|
// oss << g_Config.m_SvScoreFolder << "/" << g_Config.m_SvMap << "_record.dtb";
|
||||||
|
//else
|
||||||
|
oss << g_Config.m_SvMap << "_record.dtb";
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::SaveScoreThread(void *pUser)
|
||||||
|
{
|
||||||
|
CFileScore *pSelf = (CFileScore *)pUser;
|
||||||
|
lock_wait(gs_ScoreLock);
|
||||||
|
std::fstream f;
|
||||||
|
f.open(SaveFile().c_str(), std::ios::out);
|
||||||
|
if(!f.fail())
|
||||||
|
{
|
||||||
|
int t = 0;
|
||||||
|
for(sorted_array<CPlayerScore>::range r = pSelf->m_Top.all(); !r.empty(); r.pop_front())
|
||||||
|
{
|
||||||
|
f << r.front().m_aName << std::endl << r.front().m_Score << std::endl << r.front().m_aIP << std::endl;
|
||||||
|
//if(g_Config.m_SvCheckpointSave)
|
||||||
|
//{
|
||||||
|
for(int c = 0; c < NUM_TELEPORT; c++)
|
||||||
|
f << r.front().m_aCpTime[c] << " ";
|
||||||
|
f << std::endl;
|
||||||
|
//}
|
||||||
|
t++;
|
||||||
|
if(t%50 == 0)
|
||||||
|
thread_sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
lock_release(gs_ScoreLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::Save()
|
||||||
|
{
|
||||||
|
void *pSaveThread = thread_create(SaveScoreThread, this);
|
||||||
|
#if defined(CONF_FAMILY_UNIX)
|
||||||
|
pthread_detach((pthread_t)pSaveThread);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::Init()
|
||||||
|
{
|
||||||
|
lock_wait(gs_ScoreLock);
|
||||||
|
|
||||||
|
// create folder if not exist
|
||||||
|
//if(g_Config.m_SvScoreFolder[0])
|
||||||
|
// fs_makedir(g_Config.m_SvScoreFolder);
|
||||||
|
|
||||||
|
std::fstream f;
|
||||||
|
f.open(SaveFile().c_str(), std::ios::in);
|
||||||
|
|
||||||
|
while(!f.eof() && !f.fail())
|
||||||
|
{
|
||||||
|
std::string TmpName, TmpScore, TmpIP, TmpCpLine;
|
||||||
|
std::getline(f, TmpName);
|
||||||
|
if(!f.eof() && TmpName != "")
|
||||||
|
{
|
||||||
|
std::getline(f, TmpScore);
|
||||||
|
std::getline(f, TmpIP);
|
||||||
|
float aTmpCpTime[NUM_TELEPORT] = {0};
|
||||||
|
//if(g_Config.m_SvCheckpointSave)
|
||||||
|
//{
|
||||||
|
std::getline(f, TmpCpLine);
|
||||||
|
char *pTime = strtok((char*)TmpCpLine.c_str(), " ");
|
||||||
|
int i = 0;
|
||||||
|
while(pTime != NULL && i < NUM_TELEPORT)
|
||||||
|
{
|
||||||
|
aTmpCpTime[i] = atof(pTime);
|
||||||
|
pTime = strtok(NULL, " ");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
m_Top.add(*new CPlayerScore(TmpName.c_str(), atof(TmpScore.c_str()), TmpIP.c_str(), aTmpCpTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
lock_release(gs_ScoreLock);
|
||||||
|
|
||||||
|
// save the current best score
|
||||||
|
if(m_Top.size())
|
||||||
|
((CGameControllerDDRace*)GameServer()->m_pController)->m_CurrentRecord = m_Top[0].m_Score;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileScore::CPlayerScore *CFileScore::SearchScore(int ID, bool ScoreIP, int *pPosition)
|
||||||
|
{
|
||||||
|
char aIP[16];
|
||||||
|
Server()->GetClientIP(ID, aIP, sizeof(aIP));
|
||||||
|
|
||||||
|
int Pos = 1;
|
||||||
|
for(sorted_array<CPlayerScore>::range r = m_Top.all(); !r.empty(); r.pop_front())
|
||||||
|
{
|
||||||
|
if(!strcmp(r.front().m_aIP, aIP) /*&& g_Config.m_SvScoreIP*/ && ScoreIP)
|
||||||
|
{
|
||||||
|
if(pPosition)
|
||||||
|
*pPosition = Pos;
|
||||||
|
return &r.front();
|
||||||
|
}
|
||||||
|
Pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchName(Server()->ClientName(ID), pPosition, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileScore::CPlayerScore *CFileScore::SearchName(const char *pName, int *pPosition, bool NoCase)
|
||||||
|
{
|
||||||
|
CPlayerScore *pPlayer = 0;
|
||||||
|
int Pos = 1;
|
||||||
|
int Found = 0;
|
||||||
|
for(sorted_array<CPlayerScore>::range r = m_Top.all(); !r.empty(); r.pop_front())
|
||||||
|
{
|
||||||
|
if(str_find_nocase(r.front().m_aName, pName))
|
||||||
|
{
|
||||||
|
if(pPosition)
|
||||||
|
*pPosition = Pos;
|
||||||
|
if(NoCase)
|
||||||
|
{
|
||||||
|
Found++;
|
||||||
|
pPlayer = &r.front();
|
||||||
|
}
|
||||||
|
if(!strcmp(r.front().m_aName, pName))
|
||||||
|
return &r.front();
|
||||||
|
}
|
||||||
|
Pos++;
|
||||||
|
}
|
||||||
|
if(Found > 1)
|
||||||
|
{
|
||||||
|
if(pPosition)
|
||||||
|
*pPosition = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::UpdatePlayer(int ID, float Score, float aCpTime[NUM_TELEPORT])
|
||||||
|
{
|
||||||
|
const char *pName = Server()->ClientName(ID);
|
||||||
|
char aIP[16];
|
||||||
|
Server()->GetClientIP(ID, aIP, sizeof(aIP));
|
||||||
|
|
||||||
|
lock_wait(gs_ScoreLock);
|
||||||
|
CPlayerScore *pPlayer = SearchScore(ID, 1, 0);
|
||||||
|
|
||||||
|
if(pPlayer)
|
||||||
|
{
|
||||||
|
for(int c = 0; c < NUM_TELEPORT; c++)
|
||||||
|
pPlayer->m_aCpTime[c] = aCpTime[c];
|
||||||
|
|
||||||
|
pPlayer->m_Score = Score;
|
||||||
|
str_copy(pPlayer->m_aName, pName, sizeof(pPlayer->m_aName));
|
||||||
|
|
||||||
|
sort(m_Top.all());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_Top.add(*new CPlayerScore(pName, Score, aIP, aCpTime));
|
||||||
|
|
||||||
|
lock_release(gs_ScoreLock);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::LoadScore(int ClientID)
|
||||||
|
{
|
||||||
|
char aIP[16];
|
||||||
|
Server()->GetClientIP(ClientID, aIP, sizeof(aIP));
|
||||||
|
CPlayerScore *pPlayer = SearchScore(ClientID, 0, 0);
|
||||||
|
if(pPlayer && strcmp(pPlayer->m_aIP, aIP) != 0)
|
||||||
|
{
|
||||||
|
lock_wait(gs_ScoreLock);
|
||||||
|
str_copy(pPlayer->m_aIP, aIP, sizeof(pPlayer->m_aIP));
|
||||||
|
lock_release(gs_ScoreLock);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// set score
|
||||||
|
if(pPlayer)
|
||||||
|
PlayerData(ClientID)->Set(pPlayer->m_Score, pPlayer->m_aCpTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::SaveScore(int ClientID, float Time, CCharacter *pChar)
|
||||||
|
{
|
||||||
|
UpdatePlayer(ClientID, Time, pChar->m_CpCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::ShowTop5(int ClientID, int Debut)
|
||||||
|
{
|
||||||
|
char aBuf[512];
|
||||||
|
GameServer()->SendChatTarget(ClientID, "----------- Top 5 -----------");
|
||||||
|
for(int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
if(i+Debut > m_Top.size())
|
||||||
|
break;
|
||||||
|
CPlayerScore *r = &m_Top[i+Debut-1];
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%d. %s Time: %d minute(s) %5.2f second(s)",
|
||||||
|
i+Debut, r->m_aName, (int) r->m_Score/60, r->m_Score-((int)r->m_Score/60*60));
|
||||||
|
GameServer()->SendChatTarget(ClientID, aBuf);
|
||||||
|
}
|
||||||
|
GameServer()->SendChatTarget(ClientID, "------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileScore::ShowRank(int ClientID, const char* pName, bool Search)
|
||||||
|
{
|
||||||
|
CPlayerScore *pScore;
|
||||||
|
int Pos;
|
||||||
|
char aBuf[512];
|
||||||
|
|
||||||
|
if(!Search)
|
||||||
|
pScore = SearchScore(ClientID, 1, &Pos);
|
||||||
|
else
|
||||||
|
pScore = SearchName(pName, &Pos, 1);
|
||||||
|
|
||||||
|
if(pScore && Pos > -1)
|
||||||
|
{
|
||||||
|
float Time = pScore->m_Score;
|
||||||
|
char aClientName[128];
|
||||||
|
str_format(aClientName, sizeof(aClientName), " (%s)", Server()->ClientName(ClientID));
|
||||||
|
if(!g_Config.m_SvHideScore)
|
||||||
|
str_format(aBuf, sizeof(aBuf), "Your time: %d minute(s) %5.2f second(s)", (int)Time/60, Time-((int)Time/60*60));
|
||||||
|
else
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%d. %s Time: %d minute(s) %5.2f second(s)", Pos, pScore->m_aName, (int)Time/60, Time-((int)Time/60*60));
|
||||||
|
if(Search)
|
||||||
|
strcat(aBuf, aClientName);
|
||||||
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(Pos == -1)
|
||||||
|
str_format(aBuf, sizeof(aBuf), "Several players were found.");
|
||||||
|
else
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%s is not ranked", Search?pName:Server()->ClientName(ClientID));
|
||||||
|
|
||||||
|
GameServer()->SendChatTarget(ClientID, aBuf);
|
||||||
|
}
|
54
src/game/server/score/file_score.h
Normal file
54
src/game/server/score/file_score.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/* copyright (c) 2008 rajh and gregwar. Score stuff */
|
||||||
|
|
||||||
|
#ifndef GAME_SERVER_FILESCORE_H
|
||||||
|
#define GAME_SERVER_FILESCORE_H
|
||||||
|
|
||||||
|
#include <base/tl/sorted_array.h>
|
||||||
|
|
||||||
|
#include "../score.h"
|
||||||
|
|
||||||
|
class CFileScore : public IScore
|
||||||
|
{
|
||||||
|
CGameContext *m_pGameServer;
|
||||||
|
IServer *m_pServer;
|
||||||
|
|
||||||
|
class CPlayerScore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char m_aName[MAX_NAME_LENGTH];
|
||||||
|
float m_Score;
|
||||||
|
char m_aIP[16];
|
||||||
|
float m_aCpTime[NUM_TELEPORT];
|
||||||
|
|
||||||
|
CPlayerScore() {};
|
||||||
|
CPlayerScore(const char *pName, float Score, const char *pIP, float aCpTime[NUM_TELEPORT]);
|
||||||
|
|
||||||
|
bool operator<(const CPlayerScore& other) { return (this->m_Score < other.m_Score); }
|
||||||
|
};
|
||||||
|
|
||||||
|
sorted_array<CPlayerScore> m_Top;
|
||||||
|
|
||||||
|
CGameContext *GameServer() { return m_pGameServer; }
|
||||||
|
IServer *Server() { return m_pServer; }
|
||||||
|
|
||||||
|
CPlayerScore *SearchScore(int ID, bool ScoreIP, int *pPosition);
|
||||||
|
CPlayerScore *SearchName(const char *pName, int *pPosition, bool MatchCase);
|
||||||
|
void UpdatePlayer(int ID, float Score, float aCpTime[NUM_TELEPORT]);
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Save();
|
||||||
|
static void SaveScoreThread(void *pUser);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CFileScore(CGameContext *pGameServer);
|
||||||
|
~CFileScore();
|
||||||
|
|
||||||
|
virtual void LoadScore(int ClientID);
|
||||||
|
virtual void SaveScore(int ClientID, float Time, CCharacter *pChar);
|
||||||
|
|
||||||
|
virtual void ShowTop5(int ClientID, int Debut=1);
|
||||||
|
virtual void ShowRank(int ClientID, const char* pName, bool Search=false);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue