在某石软件挺苦逼游戏上线后,天天加班,一周一次版本,而且游戏数据并没有好转,后来换了一家游戏公司叫做某玩游戏,
但是那个时代腾讯的游戏不是很出名,那时候腾讯去某石挖人,整个团队挖人,其实鹅厂只是在手机互联网后面才发力,
那时候才虹吸了社会技术人才。
某玩当年的老板叫廖老板,当年可是财大气粗,王校长也投资,当年网易都看着页游时代物欲横流,看着这边土老板们狂赚钱,
那时候某玩打算做一款奇迹类型的游戏,然而我们当时技术团队大概这样,前端8个 后端8个人,前端才用的flash as,后端采用的是c++ linux,对主语这种奇迹类型的mmo,几个东西必须处理好的,一个战斗,一个aoi同步。当年的设计方案也是独特一绝,在游戏网关存放用户在场景的屏索引、位置信息,游戏的aoi事件通过网络把传到网关,网关再把aoi消息转发到客户端
template <class NPC>
void gateway_screen_index::traverse_every_screen(const uint32 screen,callback<NPC> &cb)
{
wrlock.rdlock();
Screen2PlayerSet::iterator iter = index.find(screen);
if(iter != index.end())
{
PlayerSet &set = iter->second;
PlayerSet::iterator it = set.begin(), ed = set.end();
for(; it != ed; ++it)
{
cb.invoke(*it);
}
}
wrlock.unlock();
}
struct SendNineExec : public callback<gateway_player>
{
const void *_cmd;
uint32 _cmdLen;
//int _sendLen;
//bool zip;
//t_StackCmdQueue cmd_queue;
SendNineExec(const void *cmd , const int cmdLen):_cmd(cmd),_cmdLen(cmdLen)
{
}
bool invoke(gateway_player *player)
{
player->sendmsgToMe(_cmd , _cmdLen);
//debug_log("player %d %s",player->id,player->name.c_str());
//MSG::base_msg* msg = (MSG::base_msg*)_cmd;
//debug_log("玩家%s,%u,收到------- %u,%u九屏信息", player->name.c_str(), player->id, msg->first, msg->second);
return true;
}
};
void gateway_screen_index::sendmsgToNine(const uint32 posi, const void *pMsg, const int msgLen)
{
SendNineExec exec(pMsg , msgLen);
const screen_vector &pv = get_view(posi);
screen_vector::const_iterator it = pv.begin(), ed = pv.end();
for(; it != ed; ++it)
{
traverse_every_screen(*it , exec);
}
}
void gateway_screen_index::sendmsgToDirect(const screen posi, const int direct, const void *pMsg, const int msgLen)
{
SendNineExec exec(pMsg , msgLen);
const screen_vector &pv = get_direct_view(posi, direct);
//Zebra::logger->debug("屏编号:%d,前向屏数量:%d",posi,pv.size());
screen_vector::const_iterator it = pv.begin(), ed = pv.end();
for(; it != ed; ++it)
{
/*
Cmd::t_NullCmd *ptNullCmd = (Cmd::t_NullCmd *)pMsg;
Zebra::logger->debug("%s屏索引%d,消息:(%d,%d)",__FUNCTION__,*it,ptNullCmd->cmd,ptNullCmd->para);
// */
traverse_every_screen(*it , exec);
}
}
void gateway_screen_index::sendmsgToReverseDirect(const screen posi, const int direct, const void *pMsg, const int msgLen)
{
SendNineExec exec(pMsg , msgLen);
const screen_vector &pv = get_reverse_direct_view(posi, direct);
screen_vector::const_iterator it = pv.begin(), ed = pv.end();
for(; it != ed; ++it)
{
/*
Cmd::t_NullCmd *ptNullCmd = (Cmd::t_NullCmd *)pMsg;
Zebra::logger->debug("屏%d,方向%d的后向屏索引%d,消息:(%d,%d)",posi,direct,*it,ptNullCmd->cmd,ptNullCmd->para);
// */
traverse_every_screen(*it , exec);
}
}
struct SendNineCampExec : public callback<gateway_player>
{
const uint16 _camp_id;
const void *_cmd;
uint32 _cmdLen;
int _sendLen;
bool zip;
t_StackCmdQueue cmd_queue;
SendNineCampExec(const uint16 campID, const void *cmd , const int cmdLen) : _camp_id(campID), _cmd(cmd),_cmdLen(cmdLen)
{
}
bool invoke(gateway_player *player)
{
/*if(player->country->campID == _camp_id)
{
player->sendmsgToMe(_cmd , _cmdLen);
}
*/
return true;
}
};
void gateway_screen_index::sendmsgToCampNine(const screen posi, const uint16 campID, const void *pMsg, const int msgLen)
{
SendNineCampExec exec(campID, pMsg , msgLen);
const screen_vector &pv = get_view(posi);
screen_vector::const_iterator it = pv.begin(), ed = pv.end();
for(; it != ed; ++it)
{
traverse_every_screen(*it , exec);
}
}
void gateway_screen_index::sendmsgToCampDirect(const screen posi, const uint16 campID, const int direct, const void *pMsg, const int msgLen)
{
SendNineCampExec exec(campID, pMsg, msgLen);
const screen_vector &pv = get_direct_view(posi, direct);
screen_vector::const_iterator it = pv.begin(), ed = pv.end();
for(; it != ed; ++it)
{
traverse_every_screen(*it , exec);
}
}
void gateway_screen_index::sendmsgToCampReverseDirect(const screen posi, const uint16 campID, const int direct, const void *pMsg, const int msgLen)
{
SendNineCampExec exec(campID, pMsg, msgLen);
const screen_vector &pv = get_reverse_direct_view(posi, direct);
screen_vector::const_iterator it = pv.begin(), ed = pv.end();
for(; it != ed; ++it)
{
traverse_every_screen(*it , exec);
}
}
struct SendNineExecExceptMe : public callback<gateway_player>
{
const uint32 _exceptme_id;
const void *_cmd;
uint32 _cmdLen;
uint32 _type;
char _name[MAX_NAME_LEN];
int _sendLen;
t_StackCmdQueue cmd_queue;
SendNineExecExceptMe(const uint32 exceptme_id, const void *cmd , const int cmdLen):_exceptme_id(exceptme_id),_cmd(cmd),_cmdLen(cmdLen)
{
}
bool invoke(gateway_player *player)
{
if (_exceptme_id != player->id)
player->sendmsgToMe(_cmd , _cmdLen);
return true;
}
};
void gateway_screen_index::sendmsgToNineExceptMe(const uint32 posi, const uint32 exceptme_id, const void *pMsg, const int msgLen)
{
SendNineExecExceptMe exec(exceptme_id, pMsg , msgLen);
const screen_vector &pv = get_view(posi);
screen_vector::const_iterator it = pv.begin(), ed = pv.end();
for(; it != ed; ++it)
{
traverse_every_screen(*it , exec);
}
}
void gateway_screen_index::sendmsgToAll(const void *pMsg, const int msgLen)
{
PlayerSet::iterator it = all.begin();
for(; it != all.end() ; ++it)
{
(*it)->sendmsgToMe(pMsg,msgLen);
}
}
bool gateway_screen_index::refresh(gateway_player *e, const uint32 newIndex)
{
if(e==NULL) return false;
//-2 表示删除状态,不可以被场景添加
//-1 表示等待添加状态
if(e->getIndexKey() == (uint32)-2 && newIndex != (uint32)-1) return false;
if(e->inserted)
{
//已经加入地图索引,只是在屏之间来回切换
debug_log("[已经加入地图索引,只是在屏之间来回切换");
bool ret=false;
wrlock.wrlock();
PlayerSet &pimi = index[e->getIndexKey()];
PlayerSet::const_iterator it = pimi.find(e);
if (it != pimi.end())
{
debug_log("[地图索引]切换: %u, %u", e->getIndexKey(), newIndex);
ret=true;
pimi.erase(it);
index[newIndex].insert(e);
e->setIndexKey(newIndex);
}
wrlock.unlock();
return ret;
}
else if (newIndex != (uint32)-1)
{
//在全局索引中添加
if (all.insert(e).second)
{
debug_log("[地图索引]加入: %u, %u",e->getIndexKey(), newIndex);
//新加入地图索引
wrlock.wrlock();
index[newIndex].insert(e);
wrlock.unlock();
}
else
{
debug_log("[地图索引]加入失败,已经在索引中: %u, %u",e->getIndexKey(), newIndex);
}
e->inserted=true;
}
e->setIndexKey(newIndex);
//e->debug("屏索引x:%d,%d,%d",e->setIndexKey(newIndex),e->getIndexKey(),newIndex);
return e->inserted;
}
void gateway_screen_index::remove_gateway_player(gateway_player *e)
{
if(e==NULL || !e->inserted) return;
wrlock.wrlock();
PlayerSet::iterator it = all.find(e);
if (it != all.end())
{
//e->debug("[地图索引]删除: %u", e->getIndexKey());
PlayerSet &pimi = index[e->getIndexKey()];
e->setIndexKey((uint32)-2);
//在全局索引中删除
all.erase(it);
//在屏索引中删除
pimi.erase(e);
// 把自己从必要的玩家中删除
e->inserted=false;
}
else
{
error_log("地图%u中找不到玩家(%u,%s)",e->mapid,e->id, e->name.c_str());
}
wrlock.unlock();
}