从服务器排序并分发到客户端或发送未排序并让客户端对其进行排序更好吗?

时间:2017-01-14 15:28:28

标签: c++ sorting server client online-game

这是一款在线游戏,我付钱实现了一个游戏事件,即玩家与玩家游戏系统。

在我的设计中,我有一个服务器端类(名为PvpEventManager,它是事件管理器,当玩家加入或离开事件时,它会在玩家加入或离开事件时处理,无论是通过决定,还是断开连接等等,还有许多其他功能。

现在,此类还包含一个容器,其中包含事件期间的播放器信息(名为vPlayerInfo),用于各种处理。当玩家杀死其他人时,他的kill必须增加,而受害者death也是如此。但是,客户端也有一个记分板,因为它是处理kill的服务器工作,并告诉所有其他关于此事件的客户端,容器将得到更新。

必须将容器从kill struct member按升序降序排序,以便可以正确地呈现(在客户端)记分板。

什么会更好?

  • 在服务器上对容器进行排序,增加服务器工作量,并将已经排序的准备好的屏幕渲染容器发送给所有客户端。
  • 发送未分类的容器,让每个连接的游戏客户端在接收容器时对其进行排序。

请注意,服务器处理成千上万的数据包传入和输出每个时钟点并真正处理 A LOT A LOT 其他的东西。

这有点描述了它的设计:

Event Design

此代码描述了在实际代码的一部分上对容器进行排序时所执行的操作。

#include <iostream>
#include <array>
#include <vector>
#include <map>
#include <algorithm>

struct PlayerScoreBoardInfo
{
    std::string name;
    unsigned int kill, death, suicide;
    unsigned int scorestreak;
    PlayerScoreBoardInfo()
    {
        kill = death = suicide = scorestreak = 0;
        name = "";
    }
    explicit PlayerScoreBoardInfo( std::string strname, unsigned int nkill, unsigned int ndeath, unsigned int nsuicide, unsigned int nscorestreak ) : 
        name(strname), kill(nkill), death(ndeath), suicide(nsuicide), scorestreak(nscorestreak)
    {

    }
};

class GameArenaManager
{
private:
    GameArenaManager() {}
public:
    std::map<u_long, PlayerScoreBoardInfo> m_Infos;
public:
    static GameArenaManager& GetInstance()
    {
        static GameArenaManager InstanceObj;
        return InstanceObj;
    }
};

template <typename T1, typename T2> inline void SortVecFromMap( std::map<T1,T2>& maptodosort, std::vector<T2>& vectosort )
{
    std::vector<T1> feedvector;
    feedvector.reserve( maptodosort.size() );

    for( const auto& it : maptodosort )
        feedvector.push_back(it.second.kill);

    std::sort(feedvector.begin(), feedvector.end(), std::greater<T1>());

    for(const auto& itV : feedvector ) {
        for( const auto& itM : maptodosort ) { 
            if( itM.second.kill == itV )  {
                vectosort.push_back(itM.second );
            }
        }
    }
}

int main()
{
    GameArenaManager& Manager = GameArenaManager::GetInstance();
    PlayerScoreBoardInfo info[5];
    info[0] = PlayerScoreBoardInfo("ArchedukeShrimp", 5,4,0,0);
    info[1] = PlayerScoreBoardInfo("EvilLactobacilus", 9,4,0,0);
    info[2] = PlayerScoreBoardInfo("DolphinetelyOrcaward", 23,4,0,0);
    info[3] = PlayerScoreBoardInfo("ChuckSkeet", 1,4,0,0);
    info[4] = PlayerScoreBoardInfo("TrumpMcDuck", 87,4,0,0);
    for( int i=0; i<5; i++)
        Manager.m_Infos.insert( std::make_pair( i, info[i] ) ); 

    std::vector<PlayerScoreBoardInfo> sortedvec;
    SortVecFromMap( Manager.m_Infos, sortedvec );

    for( std::vector<PlayerScoreBoardInfo>::iterator it = sortedvec.begin(); it != sortedvec.end(); it++ )
    {
        std::cout << "Name: "   <<  (*it).name.c_str()  << " ";
        std::cout << "Kills: "  <<  (*it).kill          << std::endl;
    }

    return 0;
}

以下是ideone编译代码的链接:http://ideone.com/B08y9l

Wandbox的一个链接,以防您想要实时编辑编译:http://melpon.org/wandbox/permlink/6OVLBGEXiux5Vn34

1 个答案:

答案 0 :(得分:1)

这个问题可能会被关闭为#34;关闭主题&#34;。然而,

第一个问题:服务器是否需要排序记分板?

如果没有,为什么要这么做?

如果有的话,服务器会想要按玩家ID索引记分板,该ID要求按ID排序(以帮助二进制搜索)或使用散列容器(O1搜索时间)。

此外,最终的瓶颈是网络带宽。您最终希望能够发送记分板增量而不是世界状态消息。

这进一步证明了让客户做出诉诸的工作。

还有一个哲学论点:

除主键以外的任何内容是按数据关注还是显示问题进行排序?这是一个表达问题。

演示文稿是什么?客户。

QED