CLuaUi::CLuaUi() { mem_zero(this, sizeof(CLuaUi)); }
void CGameClient::OnPredict() { // store the previous values so we can detect prediction errors CCharacterCore BeforePrevChar = m_PredictedPrevChar; CCharacterCore BeforeChar = m_PredictedChar; // we can't predict without our own id or own character if(m_LocalClientID == -1 || !m_Snap.m_aCharacters[m_LocalClientID].m_Active) return; // don't predict anything if we are paused or round/game is over if(m_Snap.m_pGameData && m_Snap.m_pGameData->m_GameStateFlags&(GAMESTATEFLAG_PAUSED|GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER)) { if(m_Snap.m_pLocalCharacter) m_PredictedChar.Read(m_Snap.m_pLocalCharacter); if(m_Snap.m_pLocalPrevCharacter) m_PredictedPrevChar.Read(m_Snap.m_pLocalPrevCharacter); return; } // repredict character CWorldCore World; World.m_Tuning = m_Tuning; // search for players for(int i = 0; i < MAX_CLIENTS; i++) { if(!m_Snap.m_aCharacters[i].m_Active) continue; m_aClients[i].m_Predicted.Init(&World, Collision()); World.m_apCharacters[i] = &m_aClients[i].m_Predicted; m_aClients[i].m_Predicted.Read(&m_Snap.m_aCharacters[i].m_Cur); } // predict for(int Tick = Client()->GameTick()+1; Tick <= Client()->PredGameTick(); Tick++) { // fetch the local if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_LocalClientID]) m_PredictedPrevChar = *World.m_apCharacters[m_LocalClientID]; // first calculate where everyone should move for(int c = 0; c < MAX_CLIENTS; c++) { if(!World.m_apCharacters[c]) continue; mem_zero(&World.m_apCharacters[c]->m_Input, sizeof(World.m_apCharacters[c]->m_Input)); if(m_LocalClientID == c) { // apply player input int *pInput = Client()->GetInput(Tick); if(pInput) World.m_apCharacters[c]->m_Input = *((CNetObj_PlayerInput*)pInput); World.m_apCharacters[c]->Tick(true); } else World.m_apCharacters[c]->Tick(false); } // move all players and quantize their data for(int c = 0; c < MAX_CLIENTS; c++) { if(!World.m_apCharacters[c]) continue; World.m_apCharacters[c]->Move(); World.m_apCharacters[c]->Quantize(); } // check if we want to trigger effects if(Tick > m_LastNewPredictedTick) { m_LastNewPredictedTick = Tick; if(m_LocalClientID != -1 && World.m_apCharacters[m_LocalClientID]) ProcessTriggeredEvents(World.m_apCharacters[m_LocalClientID]->m_TriggeredEvents, World.m_apCharacters[m_LocalClientID]->m_Pos); } if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_LocalClientID]) m_PredictedChar = *World.m_apCharacters[m_LocalClientID]; } if(g_Config.m_Debug && g_Config.m_ClPredict && m_PredictedTick == Client()->PredGameTick()) { CNetObj_CharacterCore Before = {0}, Now = {0}, BeforePrev = {0}, NowPrev = {0}; BeforeChar.Write(&Before); BeforePrevChar.Write(&BeforePrev); m_PredictedChar.Write(&Now); m_PredictedPrevChar.Write(&NowPrev); if(mem_comp(&Before, &Now, sizeof(CNetObj_CharacterCore)) != 0) { Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "prediction error"); for(unsigned i = 0; i < sizeof(CNetObj_CharacterCore)/sizeof(int); i++) if(((int *)&Before)[i] != ((int *)&Now)[i]) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), " %d %d %d (%d %d)", i, ((int *)&Before)[i], ((int *)&Now)[i], ((int *)&BeforePrev)[i], ((int *)&NowPrev)[i]); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", aBuf); } } } m_PredictedTick = Client()->PredGameTick(); }
void CCharacter::TickDefered() { // advance the dummy { CWorldCore TempWorld; m_ReckoningCore.Init(&TempWorld, GameServer()->Collision()); m_ReckoningCore.Tick(false); m_ReckoningCore.Move(); m_ReckoningCore.Quantize(); } //lastsentcore vec2 StartPos = m_Core.m_Pos; vec2 StartVel = m_Core.m_Vel; bool StuckBefore = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); m_Core.Move(); bool StuckAfterMove = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); m_Core.Quantize(); bool StuckAfterQuant = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); m_Pos = m_Core.m_Pos; if(!StuckBefore && (StuckAfterMove || StuckAfterQuant)) { // Hackish solution to get rid of strict-aliasing warning union { float f; unsigned u; } StartPosX, StartPosY, StartVelX, StartVelY; StartPosX.f = StartPos.x; StartPosY.f = StartPos.y; StartVelX.f = StartVel.x; StartVelY.f = StartVel.y; char aBuf[256]; str_format(aBuf, sizeof(aBuf), "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x", StuckBefore, StuckAfterMove, StuckAfterQuant, StartPos.x, StartPos.y, StartVel.x, StartVel.y, StartPosX.u, StartPosY.u, StartVelX.u, StartVelY.u); GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); } int Events = m_Core.m_TriggeredEvents; int Mask = CmaskAllExceptOne(m_pPlayer->GetCID()); if(Events&COREEVENT_GROUND_JUMP) GameServer()->CreateSound(m_Pos, SOUND_PLAYER_JUMP, Mask); if(Events&COREEVENT_HOOK_ATTACH_PLAYER) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_PLAYER, CmaskAll()); if(Events&COREEVENT_HOOK_ATTACH_GROUND) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_GROUND, Mask); if(Events&COREEVENT_HOOK_HIT_NOHOOK) GameServer()->CreateSound(m_Pos, SOUND_HOOK_NOATTACH, Mask); if(m_pPlayer->GetTeam() == TEAM_SPECTATORS) { m_Pos.x = m_Input.m_TargetX; m_Pos.y = m_Input.m_TargetY; } IServer::CClientInfo CltInfo; Server()->GetClientInfo(m_pPlayer->GetCID(), &CltInfo); // update the m_SendCore if needed { CNetObj_Character Predicted; CNetObj_Character Current; mem_zero(&Predicted, sizeof(Predicted)); mem_zero(&Current, sizeof(Current)); m_ReckoningCore.Write(&Predicted); m_Core.Write(&Current); // only allow dead reackoning for a top of 3 seconds if(m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0 || (m_Core.m_Frozen > 0 && !(Server()->Tick()&1))) { m_ReckoningTick = Server()->Tick(); m_SendCore = m_Core; m_ReckoningCore = m_Core; } } }
static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths) { PROFILER_CPU_TIMESLICE("NVG backend renderStroke"); GLNVGcontext* gl = (GLNVGcontext*)uptr; GLNVGcall* call = glnvg__allocCall(gl); GLuint maxverts, offset; if (call == NULL) return; call->type = GLNVG_STROKE; call->pathOffset = glnvg__allocPaths(gl, npaths); if (call->pathOffset == -1) goto error; call->pathCount = npaths; call->image = paint->image; // Allocate vertices for all the paths. maxverts = glnvg__maxVertCount(paths, npaths); NVGvertex* vtx = gfx::frameAllocVertices<NVGvertex>(maxverts, &offset); if (!vtx) goto error; for (int i = 0; i < npaths; i++) { GLNVGpath* copy = &gl->paths[call->pathOffset + i]; const NVGpath* path = &paths[i]; mem_zero(copy); if (path->nstroke) { copy->strokeOffset = offset; copy->strokeCount = path->nstroke; mem_copy(vtx, path->stroke, sizeof(NVGvertex) * path->nstroke); offset += path->nstroke; vtx += path->nstroke; } } GLNVGfragUniforms* frag; gfx::dynbufAlignMem(gfx::caps.uboAlignment, &call->uniformOffset); if (gl->flags & NVG_STENCIL_STROKES) { // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, strokeWidth, fringe, -1.0f); frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, strokeWidth, fringe, 1.0f - 0.5f / 255.0f); } else { // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, strokeWidth, fringe, -1.0f); } return; error: // We get here if call alloc was ok, but something else is not. // Roll back the last call to prevent drawing it. if (gl->ncalls > 0) gl->ncalls--; }
CControls::CControls() { mem_zero(&m_LastData, sizeof(m_LastData)); }
void CGameClient::OnNewSnapshot() { m_NewTick = true; // clear out the invalid pointers mem_zero(&g_GameClient.m_Snap, sizeof(g_GameClient.m_Snap)); m_Snap.m_LocalClientID = -1; // secure snapshot { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int Index = 0; Index < Num; Index++) { IClient::CSnapItem Item; void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item); if(m_NetObjHandler.ValidateObj(Item.m_Type, pData, Item.m_DataSize) != 0) { if(g_Config.m_Debug) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "invalidated index=%d type=%d (%s) size=%d id=%d", Index, Item.m_Type, m_NetObjHandler.GetObjName(Item.m_Type), Item.m_DataSize, Item.m_ID); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); } Client()->SnapInvalidateItem(IClient::SNAP_CURRENT, Index); } } } ProcessEvents(); if(g_Config.m_DbgStress) { if((Client()->GameTick()%100) == 0) { char aMessage[64]; int MsgLen = rand()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) aMessage[i] = 'a'+(rand()%('z'-'a')); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; Msg.m_Team = rand()&1; Msg.m_pMessage = aMessage; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } } // go trough all the items in the snapshot and gather the info we want { m_Snap.m_aTeamSize[TEAM_RED] = m_Snap.m_aTeamSize[TEAM_BLUE] = 0; int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int i = 0; i < Num; i++) { IClient::CSnapItem Item; const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); if(Item.m_Type == NETOBJTYPE_CLIENTINFO) { const CNetObj_ClientInfo *pInfo = (const CNetObj_ClientInfo *)pData; int ClientID = Item.m_ID; IntsToStr(&pInfo->m_Name0, 4, m_aClients[ClientID].m_aName); IntsToStr(&pInfo->m_Clan0, 3, m_aClients[ClientID].m_aClan); m_aClients[ClientID].m_Country = pInfo->m_Country; IntsToStr(&pInfo->m_Skin0, 6, m_aClients[ClientID].m_aSkinName); m_aClients[ClientID].m_UseCustomColor = pInfo->m_UseCustomColor; m_aClients[ClientID].m_ColorBody = pInfo->m_ColorBody; m_aClients[ClientID].m_ColorFeet = pInfo->m_ColorFeet; // prepare the info if(m_aClients[ClientID].m_aSkinName[0] == 'x' || m_aClients[ClientID].m_aSkinName[1] == '_') str_copy(m_aClients[ClientID].m_aSkinName, "default", 64); m_aClients[ClientID].m_SkinInfo.m_ColorBody = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorBody); m_aClients[ClientID].m_SkinInfo.m_ColorFeet = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorFeet); m_aClients[ClientID].m_SkinInfo.m_Size = 64; // find new skin m_aClients[ClientID].m_SkinID = g_GameClient.m_pSkins->Find(m_aClients[ClientID].m_aSkinName); if(m_aClients[ClientID].m_SkinID < 0) { m_aClients[ClientID].m_SkinID = g_GameClient.m_pSkins->Find("default"); if(m_aClients[ClientID].m_SkinID < 0) m_aClients[ClientID].m_SkinID = 0; } if(m_aClients[ClientID].m_UseCustomColor) m_aClients[ClientID].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[ClientID].m_SkinID)->m_ColorTexture; else { m_aClients[ClientID].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[ClientID].m_SkinID)->m_OrgTexture; m_aClients[ClientID].m_SkinInfo.m_ColorBody = vec4(1,1,1,1); m_aClients[ClientID].m_SkinInfo.m_ColorFeet = vec4(1,1,1,1); } m_aClients[ClientID].UpdateRenderInfo(); } else if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; m_aClients[pInfo->m_ClientID].m_Team = pInfo->m_Team; m_aClients[pInfo->m_ClientID].m_Active = true; m_Snap.m_paPlayerInfos[pInfo->m_ClientID] = pInfo; m_Snap.m_NumPlayers++; if(pInfo->m_Local) { m_Snap.m_LocalClientID = Item.m_ID; m_Snap.m_pLocalInfo = pInfo; if(pInfo->m_Team == TEAM_SPECTATORS) { m_Snap.m_SpecInfo.m_Active = true; m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } } // calculate team-balance if(pInfo->m_Team != TEAM_SPECTATORS) m_Snap.m_aTeamSize[pInfo->m_Team]++; } else if(Item.m_Type == NETOBJTYPE_CHARACTER) { const void *pOld = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, Item.m_ID); m_Snap.m_aCharacters[Item.m_ID].m_Cur = *((const CNetObj_Character *)pData); if(pOld) { m_Snap.m_aCharacters[Item.m_ID].m_Active = true; m_Snap.m_aCharacters[Item.m_ID].m_Prev = *((const CNetObj_Character *)pOld); if(m_Snap.m_aCharacters[Item.m_ID].m_Prev.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Prev, Client()->PrevGameTick()); if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, Client()->GameTick()); } } else if(Item.m_Type == NETOBJTYPE_SPECTATORINFO) { m_Snap.m_pSpectatorInfo = (const CNetObj_SpectatorInfo *)pData; m_Snap.m_pPrevSpectatorInfo = (const CNetObj_SpectatorInfo *)Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_SPECTATORINFO, Item.m_ID); m_Snap.m_SpecInfo.m_SpectatorID = m_Snap.m_pSpectatorInfo->m_SpectatorID; } else if(Item.m_Type == NETOBJTYPE_GAMEINFO) { static bool s_GameOver = 0; m_Snap.m_pGameInfoObj = (const CNetObj_GameInfo *)pData; if(!s_GameOver && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) OnGameOver(); else if(s_GameOver && !(m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) OnStartGame(); s_GameOver = m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER; } else if(Item.m_Type == NETOBJTYPE_GAMEDATA) { m_Snap.m_pGameDataObj = (const CNetObj_GameData *)pData; m_Snap.m_GameDataSnapID = Item.m_ID; } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; } } // setup local pointers if(m_Snap.m_LocalClientID >= 0) { CSnapState::CCharacterInfo *c = &m_Snap.m_aCharacters[m_Snap.m_LocalClientID]; if(c->m_Active) { m_Snap.m_pLocalCharacter = &c->m_Cur; m_Snap.m_pLocalPrevCharacter = &c->m_Prev; m_LocalCharacterPos = vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y); } else if(Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, m_Snap.m_LocalClientID)) { // player died m_pControls->OnPlayerDeath(); } } else { m_Snap.m_SpecInfo.m_Active = true; if(Client()->State() == IClient::STATE_DEMOPLAYBACK && DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER && m_DemoSpecID != SPEC_FREEVIEW && m_Snap.m_aCharacters[m_DemoSpecID].m_Active) m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID; else m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } // clear out unneeded client data for(int i = 0; i < MAX_CLIENTS; ++i) { if(!m_Snap.m_paPlayerInfos[i] && m_aClients[i].m_Active) m_aClients[i].Reset(); } // update friend state for(int i = 0; i < MAX_CLIENTS; ++i) { if(i == m_Snap.m_LocalClientID || !m_Snap.m_paPlayerInfos[i] || !Friends()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)) m_aClients[i].m_Friend = false; else m_aClients[i].m_Friend = true; } // sort player infos by score mem_copy(m_Snap.m_paInfoByScore, m_Snap.m_paPlayerInfos, sizeof(m_Snap.m_paInfoByScore)); for(int k = 0; k < MAX_CLIENTS-1; k++) // ffs, bubblesort { for(int i = 0; i < MAX_CLIENTS-k-1; i++) { if(m_Snap.m_paInfoByScore[i+1] && (!m_Snap.m_paInfoByScore[i] || m_Snap.m_paInfoByScore[i]->m_Score < m_Snap.m_paInfoByScore[i+1]->m_Score)) { const CNetObj_PlayerInfo *pTmp = m_Snap.m_paInfoByScore[i]; m_Snap.m_paInfoByScore[i] = m_Snap.m_paInfoByScore[i+1]; m_Snap.m_paInfoByScore[i+1] = pTmp; } } } CTuningParams StandardTuning; CServerInfo CurrentServerInfo; Client()->GetServerInfo(&CurrentServerInfo); if(CurrentServerInfo.m_aGameType[0] != '0') { if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0) m_ServerMode = SERVERMODE_MOD; else if(mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) == 0) m_ServerMode = SERVERMODE_PURE; else m_ServerMode = SERVERMODE_PUREMOD; } }
static int glnvg__convertPaint(GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGpaint* paint, NVGscissor* scissor, float width, float fringe, float strokeThr) { PROFILER_CPU_TIMESLICE("NVG backend convertPaint"); GLNVGtexture* tex = NULL; float invxform[6]; mem_zero(frag); frag->innerCol = glnvg__premulColor(paint->innerColor); frag->outerCol = glnvg__premulColor(paint->outerColor); if (scissor->extent[0] < -0.5f || scissor->extent[1] < -0.5f) { mem_zero(frag->scissorMat); frag->scissorExt[0] = 1.0f; frag->scissorExt[1] = 1.0f; frag->scissorScale[0] = 1.0f; frag->scissorScale[1] = 1.0f; } else { nvgTransformInverse(invxform, scissor->xform); glnvg__xformToMat3x4(frag->scissorMat, invxform); frag->scissorExt[0] = scissor->extent[0]; frag->scissorExt[1] = scissor->extent[1]; frag->scissorScale[0] = ml::sqrt(scissor->xform[0] * scissor->xform[0] + scissor->xform[2] * scissor->xform[2]) / fringe; frag->scissorScale[1] = ml::sqrt(scissor->xform[1] * scissor->xform[1] + scissor->xform[3] * scissor->xform[3]) / fringe; } mem_copy(frag->extent, paint->extent, sizeof(frag->extent)); frag->strokeMult = (width*0.5f + fringe*0.5f) / fringe; frag->strokeThr = strokeThr; if (paint->image != 0) { tex = glnvg__findTexture(gl, paint->image); if (tex == NULL) return 0; if ((tex->flags & NVGL_TEXTURE_FLIP_Y) != 0) { float flipped[6]; nvgTransformScale(flipped, 1.0f, -1.0f); nvgTransformMultiply(flipped, paint->xform); nvgTransformInverse(invxform, flipped); } else { nvgTransformInverse(invxform, paint->xform); } frag->type = NSVG_SHADER_FILLIMG; if (tex->type == NVG_TEXTURE_RGBA) frag->texType = (tex->flags & NVGL_TEXTURE_PREMULTIPLIED) ? 0 : 1; else frag->texType = 2; // printf("frag->texType = %d\n", frag->texType); } else { frag->type = NSVG_SHADER_FILLGRAD; frag->radius = paint->radius; frag->feather = paint->feather; nvgTransformInverse(invxform, paint->xform); } glnvg__xformToMat3x4(frag->paintMat, invxform); return 1; }
void double_table_and_cache_hashed(bdd_manager *bddm, unsigned* some_roots, void (*update_fn)(unsigned (*new_place)(unsigned node)), unsigned *p_of_find, unsigned *q_of_find, boolean rehash_p_and_q) { unsigned *p; old_bddm = mem_alloc((size_t) sizeof (bdd_manager)); *old_bddm = *bddm; /*make new bigger table, but only if a bigger one is possible */ if (bddm->table_total_size > BDD_MAX_TOTAL_TABLE_SIZE) { printf("\nBDD too large (>%d nodes)\n", BDD_MAX_TOTAL_TABLE_SIZE); abort(); } bddm->table_log_size++; bddm->table_size *= 2; bddm->table_overflow_increment *= 2; { unsigned desired_size = bddm->table_size + BDD_NUMBER_OF_BINS + bddm->table_overflow_increment; bddm->table_total_size = (desired_size <= BDD_MAX_TOTAL_TABLE_SIZE)? desired_size: BDD_MAX_TOTAL_TABLE_SIZE; } bddm->node_table = (bdd_record*) mem_alloc( (size_t) bddm->table_total_size * (sizeof (bdd_record))); bddm->table_mask = bddm->table_size - BDD_NUMBER_OF_BINS; bddm->table_double_trigger *= 2; bddm->table_overflow = bddm->table_size + BDD_NUMBER_OF_BINS; #ifdef _BDD_STAT_ bddm->number_double++; #endif /* initialize to unused */ bddm->table_elements = 0; mem_zero(&bddm->node_table[BDD_NUMBER_OF_BINS], (size_t) bddm->table_size * (sizeof (bdd_record))); /* initialize bddm roots to the empty list, this new list will contain the rehashed addresses of old_bddm->roots*/ MAKE_SEQUENTIAL_LIST(bddm->roots, unsigned, 1024); /*now rehash all nodes reachable from the old roots; we must be sure that the apply1 operation does not entail doubling of bddm node table: this is achieved by our having just doubled the size of the table*/ bdd_prepare_apply1(old_bddm); for (p = SEQUENTIAL_LIST(old_bddm->roots); *p ; p++) { bdd_apply1(old_bddm, *p, bddm, &double_leaf_fn); } /*also make sure to rehash portion that is accessible from some_roots*/ for (p = some_roots; *p; p++) { if (*p != BDD_UNDEF) *p = bdd_apply1_dont_add_roots(old_bddm, *p, bddm, &double_leaf_fn); } /*and fix values p_of_find and q_of_find if indicated*/ if (rehash_p_and_q) { *p_of_find = bdd_apply1_dont_add_roots(old_bddm, *p_of_find, bddm, &double_leaf_fn); *q_of_find = bdd_apply1_dont_add_roots(old_bddm, *q_of_find, bddm, &double_leaf_fn); } /*perform user supplied updates*/ if (update_fn) (*update_fn)(&get_new_r); /*old_table now contains nodes whose mark field designates the new position of the node*/ if (bddm->cache) { if (bddm->cache_erase_on_doubling) { bdd_kill_cache(bddm); bdd_make_cache(bddm, 2 * bddm->cache_size * CACHE_NUMBER_OF_BINS, 2 * bddm->cache_overflow_increment * CACHE_NUMBER_OF_BINS); } else /*this is only a good idea when bddm is different from the managers the current apply operation is performed over*/ double_cache(bddm, &get_new_r); } old_bddm->cache = (cache_record*) 0; /* old cache has been deallocated by now*/ /*deallocated old table and old roots*/ bdd_kill_manager(old_bddm); }
void CSounds::ClearQueue() { mem_zero(m_aQueue, sizeof(m_aQueue)); m_QueuePos = 0; m_QueueWaitTime = time_get(); }
void CCountryFlags::LoadCountryflagsIndexfile() { // read file data into buffer const char *pFilename = "countryflags/index.json"; IOHANDLE File = Storage()->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL); if(!File) { Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", "couldn't open index file"); return; } int FileSize = (int)io_length(File); char *pFileData = (char *)mem_alloc(FileSize, 1); io_read(File, pFileData, FileSize); io_close(File); // parse json data json_settings JsonSettings; mem_zero(&JsonSettings, sizeof(JsonSettings)); char aError[256]; json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, FileSize, aError); mem_free(pFileData); if(pJsonData == 0) { Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, pFilename, aError); return; } // extract data const json_value &rInit = (*pJsonData)["country codes"]; if(rInit.type == json_object) { enum { NUM_INDICES = 2, }; const char *paIndices[NUM_INDICES] = {"custom", "ISO 3166-1"}; for(int Index = 0; Index < NUM_INDICES; ++Index) { const json_value &rStart = rInit[(const char *)paIndices[Index]]; if(rStart.type == json_array) { for(unsigned i = 0; i < rStart.u.array.length; ++i) { char aBuf[64]; // validate country code int CountryCode = (json_int_t)rStart[i]["code"]; if(CountryCode < CODE_LB || CountryCode > CODE_UB) { str_format(aBuf, sizeof(aBuf), "country code '%i' not within valid code range [%i..%i]", CountryCode, CODE_LB, CODE_UB); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aBuf); continue; } // add entry const char *pCountryName = rStart[i]["id"]; CCountryFlag CountryFlag; CountryFlag.m_CountryCode = CountryCode; str_copy(CountryFlag.m_aCountryCodeString, pCountryName, sizeof(CountryFlag.m_aCountryCodeString)); if(g_Config.m_ClLoadCountryFlags) { // load the graphic file CImageInfo Info; str_format(aBuf, sizeof(aBuf), "countryflags/%s.png", pCountryName); if(!Graphics()->LoadPNG(&Info, aBuf, IStorage::TYPE_ALL)) { char aMsg[64]; str_format(aMsg, sizeof(aMsg), "failed to load '%s'", aBuf); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aMsg); continue; } CountryFlag.m_Texture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0); mem_free(Info.m_pData); } m_aCountryFlags.add_unsorted(CountryFlag); // print message if(g_Config.m_Debug) { str_format(aBuf, sizeof(aBuf), "loaded country flag '%s'", pCountryName); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aBuf); } } } } } // clean up json_value_free(pJsonData); m_aCountryFlags.sort_range(); // find index of default item int DefaultIndex = 0, Index = 0; for(sorted_array<CCountryFlag>::range r = m_aCountryFlags.all(); !r.empty(); r.pop_front(), ++Index) if(r.front().m_CountryCode == -1) { DefaultIndex = Index; break; } // init LUT if(DefaultIndex != 0) for(int i = 0; i < CODE_RANGE; ++i) m_CodeIndexLUT[i] = DefaultIndex; else mem_zero(m_CodeIndexLUT, sizeof(m_CodeIndexLUT)); for(int i = 0; i < m_aCountryFlags.size(); ++i) m_CodeIndexLUT[max(0, (m_aCountryFlags[i].m_CountryCode-CODE_LB)%CODE_RANGE)] = i; }
void CSqlScore::ShowRankThread(void *pUser) { lock_wait(gs_SqlLock); CSqlScoreData *pData = (CSqlScoreData *)pUser; // Connect to database if(pData->m_pSqlData->Connect()) { try { // check strings char originalName[MAX_NAME_LENGTH]; strcpy(originalName,pData->m_aName); pData->m_pSqlData->ClearString(pData->m_aName); // check sort methode char aBuf[600]; pData->m_pSqlData->m_pStatement->execute("SET @rownum := 0;"); str_format(aBuf, sizeof(aBuf), "SELECT Rank, one_rank.Name, one_rank.Time, UNIX_TIMESTAMP(CURRENT_TIMESTAMP)-UNIX_TIMESTAMP(r.Timestamp) as Ago, UNIX_TIMESTAMP(r.Timestamp) as stamp " "FROM (" "SELECT * FROM (" "SELECT @rownum := @rownum + 1 AS RANK, Name, Time " "FROM (" "SELECT Name, min(Time) as Time " "FROM %s_%s_race " "Group By Name) as all_top_times " "ORDER BY Time ASC) as all_ranks " "WHERE all_ranks.Name = '%s') as one_rank " "LEFT JOIN %s_%s_race as r " "ON one_rank.Name = r.Name && one_rank.Time = r.Time " "ORDER BY Ago ASC " "LIMIT 0,1" ";", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap,pData->m_aName, pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap); pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf); if(pData->m_pSqlData->m_pResults->rowsCount() != 1) { str_format(aBuf, sizeof(aBuf), "%s is not ranked", originalName); pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf); } else { pData->m_pSqlData->m_pResults->next(); int since = (int)pData->m_pSqlData->m_pResults->getInt("Ago"); char agoString[40]; mem_zero(agoString, sizeof(agoString)); agoTimeToString(since,agoString); float Time = (float)pData->m_pSqlData->m_pResults->getDouble("Time"); int Rank = (int)pData->m_pSqlData->m_pResults->getInt("Rank"); 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)", Rank, pData->m_pSqlData->m_pResults->getString("Name").c_str(), (int)(Time/60), Time-((int)Time/60*60), agoString); if(pData->m_pSqlData->m_pResults->getInt("stamp") != 0){ pData->m_pSqlData->GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf, pData->m_ClientID); str_format(aBuf, sizeof(aBuf), "Finished: %s ago", agoString); } if(pData->m_Search) strcat(aBuf, pData->m_aRequestingPlayer); pData->m_pSqlData->GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf, pData->m_ClientID); } dbg_msg("SQL", "Showing rank done"); // delete results and statement delete pData->m_pSqlData->m_pResults; delete pData->m_pSqlData->m_pStatement; } catch (sql::SQLException &e) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what()); dbg_msg("SQL", aBuf); dbg_msg("SQL", "ERROR: Could not show rank"); } // disconnect from database pData->m_pSqlData->Disconnect();//TODO:Check if an exception is caught will this still execute ? } delete pData; lock_release(gs_SqlLock); }
int main(void) { dbg_logger_stdout(); char aUserdir[1024] = {0}; char aPixelFile[1024] = {0}; int PngCounter = 0; fs_storage_path("Teeworlds", aUserdir, sizeof(aUserdir)); str_format(aPixelFile, sizeof(aPixelFile), "%s/tmp/pixelstream/video.stream", aUserdir); IOHANDLE PixelStream = io_open(aPixelFile, IOFLAG_READ); long long t = 0; long long tOld = 0; long long tOldAdj = 0; unsigned char *pData = 0; unsigned char *pDataOld = 0; unsigned char *pDataMixed = 0; unsigned char *pTempRow = 0; CThreadData *pThreadData = new CThreadData(); mem_zero(pThreadData, sizeof(CThreadData)); int64 StartTime = time_get(); int64 SpeedTime = time_get(); while(PixelStream) { int Size = 0; int W = 0; int H = 0; int len = io_read(PixelStream, &t, sizeof(t)); io_read(PixelStream, &Size, sizeof(Size)); io_read(PixelStream, &W, sizeof(W)); io_read(PixelStream, &H, sizeof(H)); if (len == 0) break; if (!pData) pData = new unsigned char[Size]; if (!pDataOld) pDataOld = new unsigned char[Size]; if (!pDataMixed) pDataMixed = new unsigned char[Size]; if (!pTempRow) pTempRow = new unsigned char[W * 3]; io_read(PixelStream, pData, Size); if (pThreadData->m_Size == 0) { pThreadData->m_Size = Size; pThreadData->m_H = H; pThreadData->m_W = W; thread_detach(thread_create(RotThread, pThreadData)); } int i = 0; while(1) { if (pThreadData->m_pDataIn[i] == 0) { pThreadData->m_CounterIn++; pThreadData->m_aIndexIn[i] = pThreadData->m_CounterIn; unsigned char *p = new unsigned char[Size]; mem_copy(p, pData, Size); pThreadData->m_pDataIn[i] = p; } i++; if (i == 10) break; if (THREADWAITDELAY) thread_sleep(THREADWAITDELAY); } while(1) { int MinIndex = 0; int MinI= 0; for (int i = 0; i < 10; i++) { if (pThreadData->m_pDataOut[i] != 0 && (MinIndex == 0 || MinIndex > pThreadData->m_aIndexOut[i])) { MinIndex = pThreadData->m_aIndexOut[i]; MinI = i; } } if (MinIndex != 0) { mem_copy(pData, pThreadData->m_pDataOut[MinI], Size); delete []pThreadData->m_pDataOut[MinI]; pThreadData->m_pDataOut[MinI] = 0; break; } if (THREADWAITDELAY) thread_sleep(THREADWAITDELAY); } float tAdj = 0.0f; if (tOld && tOld + tAdj + FRAMETIME < t) { while(tOld && tOld + tAdj + FRAMETIME < t) { PngCounter++; char aBuf[1024]; if (PngCounter < 10) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0000%i.png", aUserdir, PngCounter); if (PngCounter < 100) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png000%i.png", aUserdir, PngCounter); if (PngCounter < 1000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png00%i.png", aUserdir, PngCounter); if (PngCounter < 10000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0%i.png", aUserdir, PngCounter); if (PngCounter < 100000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png%i.png", aUserdir, PngCounter); #if THREADCOUNT > 0 CBlendThreadData *apBlendData[THREADCOUNT]; for (int i = 0; i < THREADCOUNT; i++) { apBlendData[i] = new CBlendThreadData(); mem_zero(apBlendData[i], sizeof(CBlendThreadData)); apBlendData[i]->m_pIn1 = pData; apBlendData[i]->m_pIn2 = pDataOld; apBlendData[i]->m_pOut = pDataMixed; apBlendData[i]->m_Size = Size; apBlendData[i]->m_Steps = THREADCOUNT; apBlendData[i]->m_Start = i; apBlendData[i]->m_Mix = 1.0f - (tAdj + FRAMETIMEHALF) / ((float)(t - tOld)); thread_detach(thread_create(BlendThread, apBlendData[i])); } while (1) { bool Done = true; for (int i = 0; i < THREADCOUNT; i++) { if (apBlendData[i]->m_Finished == false) { Done = false; break; } } if (THREADWAITDELAY) thread_sleep(THREADWAITDELAY); if (Done) break; } #else for (int i = 0; i < Size; i++) { pDataMixed[i] = mix(pData[i], pDataOld[i], 1.0f - (tAdj + FRAMETIMEHALF) / ((float)(t - tOld))); } #endif png_t Png; png_init(0,0); png_open_file_write(&Png, aBuf); // ignore_convention png_set_data(&Png, W, H, 8, PNG_TRUECOLOR, (unsigned char *)pDataMixed); // ignore_convention png_close_file(&Png); // ignore_convention if (time_get() - SpeedTime > time_freq()) { dbg_msg("Frame", "%i (Avg: %.2f s)", PngCounter, ((float)(time_get() - StartTime) / (float)time_freq()) / (float)PngCounter); dbg_msg("FPS", "%.f", (float)PngCounter / ((float)(time_get() - StartTime) / (float)time_freq())); SpeedTime = time_get(); } tAdj = tAdj + FRAMETIME; } } else { PngCounter++; char aBuf[1024]; if (PngCounter < 10) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0000%i.png", aUserdir, PngCounter); if (PngCounter < 100) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png000%i.png", aUserdir, PngCounter); if (PngCounter < 1000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png00%i.png", aUserdir, PngCounter); if (PngCounter < 10000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png0%i.png", aUserdir, PngCounter); if (PngCounter < 100000) str_format(aBuf, sizeof(aBuf), "%s/tmp/pixelstream/png%i.png", aUserdir, PngCounter); png_t Png; png_init(0,0); png_open_file_write(&Png, aBuf); // ignore_convention png_set_data(&Png, W, H, 8, PNG_TRUECOLOR, (unsigned char *)pData); // ignore_convention png_close_file(&Png); // ignore_convention if (time_get() - SpeedTime > time_freq()) { dbg_msg("Frame", "%i (Avg: %.2f s)", PngCounter, ((float)(time_get() - StartTime) / (float)time_freq()) / (float)PngCounter); dbg_msg("FPS", "%.f", (float)PngCounter / ((float)(time_get() - StartTime) / (float)time_freq())); SpeedTime = time_get(); } } mem_copy(pDataOld, pData, Size); tOld = t; } delete[] pData; delete[] pDataOld; delete[] pDataMixed; return 0; }
int UnpackMessageID(int *pID, bool *pSys, struct CUuid *pUuid, CUnpacker *pUnpacker, CMsgPacker *pPacker) { *pID = 0; *pSys = false; mem_zero(pUuid, sizeof(*pUuid)); int MsgID = pUnpacker->GetInt(); if(pUnpacker->Error()) { return UNPACKMESSAGE_ERROR; } *pID = MsgID >> 1; *pSys = MsgID & 1; if(*pID < 0 || *pID >= OFFSET_UUID) { return UNPACKMESSAGE_ERROR; } if(*pID != 0) // NETMSG_EX, NETMSGTYPE_EX { return UNPACKMESSAGE_OK; } *pID = g_UuidManager.UnpackUuid(pUnpacker, pUuid); if(*pID == UUID_INVALID || *pID == UUID_UNKNOWN) { return UNPACKMESSAGE_ERROR; } if(*pSys) { switch(*pID) { case NETMSG_WHATIS: { CUuid Uuid2; int ID2 = g_UuidManager.UnpackUuid(pUnpacker, &Uuid2); if(ID2 == UUID_INVALID) { break; } if(ID2 == UUID_UNKNOWN) { new (pPacker) CMsgPacker(NETMSG_IDONTKNOW); pPacker->AddRaw(&Uuid2, sizeof(Uuid2)); } else { new (pPacker) CMsgPacker(NETMSG_ITIS); pPacker->AddRaw(&Uuid2, sizeof(Uuid2)); pPacker->AddString(g_UuidManager.GetName(ID2), 0); } return UNPACKMESSAGE_ANSWER; } case NETMSG_IDONTKNOW: if(g_Config.m_Debug) { CUuid Uuid2; g_UuidManager.UnpackUuid(pUnpacker, &Uuid2); if(pUnpacker->Error()) break; char aBuf[UUID_MAXSTRSIZE]; FormatUuid(Uuid2, aBuf, sizeof(aBuf)); dbg_msg("uuid", "peer: unknown %s", aBuf); } break; case NETMSG_ITIS: if(g_Config.m_Debug) { CUuid Uuid2; g_UuidManager.UnpackUuid(pUnpacker, &Uuid2); const char *pName = pUnpacker->GetString(CUnpacker::SANITIZE_CC); if(pUnpacker->Error()) break; char aBuf[UUID_MAXSTRSIZE]; FormatUuid(Uuid2, aBuf, sizeof(aBuf)); dbg_msg("uuid", "peer: %s %s", aBuf, pName); } break; } } return UNPACKMESSAGE_OK; }
int CControls::SnapInput(int *pData) { static int64 LastSendTime = 0; bool Send = false; // update player state if(m_pClient->m_pChat->IsActive()) m_InputData.m_PlayerFlags = PLAYERFLAG_CHATTING; else m_InputData.m_PlayerFlags = 0; if(m_pClient->m_pScoreboard->Active()) m_InputData.m_PlayerFlags |= PLAYERFLAG_SCOREBOARD; if(m_LastData.m_PlayerFlags != m_InputData.m_PlayerFlags) Send = true; m_LastData.m_PlayerFlags = m_InputData.m_PlayerFlags; // we freeze the input if chat or menu is activated if(m_pClient->m_pChat->IsActive() || m_pClient->m_pMenus->IsActive()) { OnReset(); mem_copy(pData, &m_InputData, sizeof(m_InputData)); // send once a second just to be sure if(time_get() > LastSendTime + time_freq()) Send = true; } else { m_InputData.m_TargetX = (int)m_MousePos.x; m_InputData.m_TargetY = (int)m_MousePos.y; if(!m_InputData.m_TargetX && !m_InputData.m_TargetY) { m_InputData.m_TargetX = 1; m_MousePos.x = 1; } // set direction m_InputData.m_Direction = 0; if(m_InputDirectionLeft && !m_InputDirectionRight) m_InputData.m_Direction = -1; if(!m_InputDirectionLeft && m_InputDirectionRight) m_InputData.m_Direction = 1; // stress testing if(g_Config.m_DbgStress) { float t = Client()->LocalTime(); mem_zero(&m_InputData, sizeof(m_InputData)); m_InputData.m_Direction = ((int)t/2)%3-1; m_InputData.m_Jump = ((int)t)&1; m_InputData.m_Fire = ((int)(t*10)); m_InputData.m_Hook = ((int)(t*2))&1; m_InputData.m_WantedWeapon = ((int)t)%NUM_WEAPONS; m_InputData.m_TargetX = (int)(sinf(t*3)*100.0f); m_InputData.m_TargetY = (int)(cosf(t*3)*100.0f); } // check if we need to send input if(m_InputData.m_Direction != m_LastData.m_Direction) Send = true; else if(m_InputData.m_Jump != m_LastData.m_Jump) Send = true; else if(m_InputData.m_Fire != m_LastData.m_Fire) Send = true; else if(m_InputData.m_Hook != m_LastData.m_Hook) Send = true; else if(m_InputData.m_WantedWeapon != m_LastData.m_WantedWeapon) Send = true; else if(m_InputData.m_NextWeapon != m_LastData.m_NextWeapon) Send = true; else if(m_InputData.m_PrevWeapon != m_LastData.m_PrevWeapon) Send = true; // send at at least 10hz if(time_get() > LastSendTime + time_freq()/25) Send = true; } // copy and return size m_LastData = m_InputData; if(!Send) return 0; LastSendTime = time_get(); mem_copy(pData, &m_InputData, sizeof(m_InputData)); return sizeof(m_InputData); }
void CMenus::RenderServerInfo(CUIRect MainView) { if(!m_pClient->m_Snap.m_pLocalInfo) return; // fetch server info CServerInfo CurrentServerInfo; Client()->GetServerInfo(&CurrentServerInfo); // render background RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); CUIRect View, ServerInfo, GameInfo, Motd; float x = 0.0f; float y = 0.0f; char aBuf[1024]; // set view to use for all sub-modules MainView.Margin(10.0f, &View); // serverinfo View.HSplitTop(View.h/2/UI()->Scale()-5.0f, &ServerInfo, &Motd); ServerInfo.VSplitLeft(View.w/2/UI()->Scale()-5.0f, &ServerInfo, &GameInfo); RenderTools()->DrawUIRect(&ServerInfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); ServerInfo.Margin(5.0f, &ServerInfo); x = 5.0f; y = 0.0f; TextRender()->Text(0, ServerInfo.x+x, ServerInfo.y+y, 32, Localize("Server info"), 250); y += 32.0f+5.0f; mem_zero(aBuf, sizeof(aBuf)); str_format( aBuf, sizeof(aBuf), "%s\n\n" "%s: %s\n" "%s: %d\n" "%s: %s\n" "%s: %s\n", CurrentServerInfo.m_aName, Localize("Address"), g_Config.m_UiServerAddress, Localize("Ping"), m_pClient->m_Snap.m_pLocalInfo->m_Latency, Localize("Version"), CurrentServerInfo.m_aVersion, Localize("Password"), CurrentServerInfo.m_Flags &1 ? Localize("Yes") : Localize("No") ); TextRender()->Text(0, ServerInfo.x+x, ServerInfo.y+y, 20, aBuf, 250); { CUIRect Button; int IsFavorite = ServerBrowser()->IsFavorite(CurrentServerInfo.m_NetAddr); ServerInfo.HSplitBottom(20.0f, &ServerInfo, &Button); static int s_AddFavButton = 0; if(DoButton_CheckBox(&s_AddFavButton, Localize("Favorite"), IsFavorite, &Button)) { if(IsFavorite) ServerBrowser()->RemoveFavorite(CurrentServerInfo.m_NetAddr); else ServerBrowser()->AddFavorite(CurrentServerInfo.m_NetAddr); } } // gameinfo GameInfo.VSplitLeft(10.0f, 0x0, &GameInfo); RenderTools()->DrawUIRect(&GameInfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); GameInfo.Margin(5.0f, &GameInfo); x = 5.0f; y = 0.0f; TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 32, Localize("Game info"), 250); y += 32.0f+5.0f; if(m_pClient->m_Snap.m_pGameInfoObj) { mem_zero(aBuf, sizeof(aBuf)); str_format( aBuf, sizeof(aBuf), "\n\n" "%s: %s\n" "%s: %s\n" "%s: %d\n" "%s: %d\n" "\n" "%s: %d/%d\n", Localize("Game type"), CurrentServerInfo.m_aGameType, Localize("Map"), CurrentServerInfo.m_aMap, Localize("Score limit"), m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit, Localize("Time limit"), m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit, Localize("Players"), m_pClient->m_Snap.m_NumPlayers, CurrentServerInfo.m_MaxClients ); TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 20, aBuf, 250); } // motd Motd.HSplitTop(10.0f, 0, &Motd); RenderTools()->DrawUIRect(&Motd, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); Motd.Margin(5.0f, &Motd); y = 0.0f; x = 5.0f; TextRender()->Text(0, Motd.x+x, Motd.y+y, 32, Localize("MOTD"), -1); y += 32.0f+5.0f; TextRender()->Text(0, Motd.x+x, Motd.y+y, 16, m_pClient->m_pMotd->m_aServerMotd, (int)Motd.w); }
unsigned CHttpDownloader::GetFileSize(const char *url, unsigned timeOut) { NETSOCKET sock; NETADDR nadd, bindAddr; mem_zero(&nadd, sizeof(nadd)); mem_zero(&bindAddr, sizeof(bindAddr)); bindAddr.type = NETTYPE_IPV4; NETURL NetUrl = CreateUrl(url); if (net_host_lookup(NetUrl.m_aHost, &nadd, NETTYPE_IPV4) != 0) { dbg_msg("HttpDownloader", "Error can't found '%s'...", NetUrl.m_aHost); return false; } nadd.port = 80; sock = net_tcp_create(bindAddr); net_socket_rcv_timeout(sock, timeOut); if (net_tcp_connect(sock, &nadd) != 0) { dbg_msg("HttpDownloader", "Error can't connect with '%s'...", NetUrl.m_aHost); net_tcp_close(sock); return false; } char aBuff[512] = {0}; str_format(aBuff, sizeof(aBuff), "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", NetUrl.m_aSlug, NetUrl.m_aHost); net_tcp_send(sock, aBuff, str_length(aBuff)); std::string NetData; int TotalBytes = 0; int CurrentRecv = 0; int nlCount = 0; char aNetBuff[1024] = {0}; do { CurrentRecv = net_tcp_recv(sock, aNetBuff, sizeof(aNetBuff)); for (int i=0; i<CurrentRecv ; i++) { if (nlCount < 2) { if (aNetBuff[i] == '\r' || aNetBuff[i] == '\n') { ++nlCount; if (NetData.size() > 0) { std::transform(NetData.begin(), NetData.end(), NetData.begin(), ::tolower); if (NetData.find("404 not found") != std::string::npos) { dbg_msg("HttpDownloader", "ERROR 404: '%s' not found...", NetUrl.m_aFile); net_tcp_close(sock); return false; } else if (NetData.find("content-length:") != std::string::npos) { char aFileSize[64]; str_copy(aFileSize, NetData.substr(15).c_str(), sizeof(aFileSize)); str_trim(aFileSize); TotalBytes = atoi(aFileSize); if (TotalBytes <= 0) { dbg_msg("HttpDownloader", "Error getting size of '%s'...", NetUrl.m_aFile); net_tcp_close(sock); return 0; } net_tcp_close(sock); return TotalBytes; } NetData.clear(); } if (aNetBuff[i] == '\r') ++i; continue; } nlCount = 0; NetData += aNetBuff[i]; } else { dbg_msg("HttpDownloader", "Error getting size of '%s'...", NetUrl.m_aFile); net_tcp_close(sock); return 0; } } } while (CurrentRecv > 0); return 0; }
int main(int argc, char **argv) // ignore_convention { int64 LastBuild = 0; NETADDR BindAddr; dbg_logger_stdout(); net_init(); mem_zero(&BindAddr, sizeof(BindAddr)); BindAddr.port = MASTERSERVER_PORT; m_NetOp.Open(BindAddr, 0); BindAddr.port = MASTERSERVER_PORT+1; m_NetChecker.Open(BindAddr, 0); // TODO: check socket for errors //mem_copy(data.header, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)); mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT)); dbg_msg("mastersrv", "started"); while(1) { m_NetOp.Update(); m_NetChecker.Update(); // process m_aPackets CNetChunk Packet; while(m_NetOp.Recv(&Packet)) { if(Packet.m_DataSize == sizeof(SERVERBROWSE_HEARTBEAT)+2 && mem_comp(Packet.m_pData, SERVERBROWSE_HEARTBEAT, sizeof(SERVERBROWSE_HEARTBEAT)) == 0) { NETADDR Alt; unsigned char *d = (unsigned char *)Packet.m_pData; Alt = Packet.m_Address; Alt.port = (d[sizeof(SERVERBROWSE_HEARTBEAT)]<<8) | d[sizeof(SERVERBROWSE_HEARTBEAT)+1]; // add it AddCheckserver(&Packet.m_Address, &Alt); } else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETCOUNT) && mem_comp(Packet.m_pData, SERVERBROWSE_GETCOUNT, sizeof(SERVERBROWSE_GETCOUNT)) == 0) { dbg_msg("mastersrv", "count requested, responding with %d", m_NumServers); CNetChunk p; p.m_ClientID = -1; p.m_Address = Packet.m_Address; p.m_Flags = NETSENDFLAG_CONNLESS; p.m_DataSize = sizeof(m_CountData); p.m_pData = &m_CountData; m_CountData.m_High = (m_NumServers>>8)&0xff; m_CountData.m_Low = m_NumServers&0xff; m_NetOp.Send(&p); } else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETLIST) && mem_comp(Packet.m_pData, SERVERBROWSE_GETLIST, sizeof(SERVERBROWSE_GETLIST)) == 0) { // someone requested the list dbg_msg("mastersrv", "requested, responding with %d m_aServers", m_NumServers); CNetChunk p; p.m_ClientID = -1; p.m_Address = Packet.m_Address; p.m_Flags = NETSENDFLAG_CONNLESS; for(int i = 0; i < m_NumPackets; i++) { p.m_DataSize = m_aPackets[i].m_Size; p.m_pData = &m_aPackets[i].m_Data; m_NetOp.Send(&p); } } }
bool CHttpDownloader::GetToFile(const char *url, const char *dest, unsigned timeOut, unsigned downloadSpeed) { if (!dest || dest[0] == 0) return false; int64 downloadTime = time_get(); unsigned chunkBytes = 0; NETSOCKET sock; NETADDR nadd, bindAddr; mem_zero(&nadd, sizeof(nadd)); mem_zero(&bindAddr, sizeof(bindAddr)); bindAddr.type = NETTYPE_IPV4; NETURL NetUrl = CreateUrl(url); if (net_host_lookup(NetUrl.m_aHost, &nadd, NETTYPE_IPV4) != 0) { dbg_msg("HttpDownloader", "Error can't found '%s'...", NetUrl.m_aHost); return false; } nadd.port = 80; sock = net_tcp_create(bindAddr); if (net_tcp_connect(sock, &nadd) != 0) { dbg_msg("HttpDownloader", "Error can't connect with '%s'...", NetUrl.m_aHost); net_tcp_close(sock); return false; } net_socket_rcv_timeout(sock, timeOut); char aBuff[512] = {0}; str_format(aBuff, sizeof(aBuff), "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", NetUrl.m_aSlug, NetUrl.m_aHost); net_tcp_send(sock, aBuff, str_length(aBuff)); std::string NetData; unsigned TotalRecv = 0; unsigned TotalBytes = 0; int CurrentRecv = 0; unsigned nlCount = 0; char aNetBuff[1024] = {0}; IOHANDLE dstFile = NULL; do { // Limit Speed if (downloadSpeed > 0) { int64 ctime = time_get(); if (ctime - downloadTime <= time_freq()) { if (chunkBytes >= downloadSpeed) { int tdff = (time_freq() - (ctime - downloadTime)) / 1000; thread_sleep(tdff); continue; } } else { chunkBytes = 0; downloadTime = time_get(); } } // CurrentRecv = net_tcp_recv(sock, aNetBuff, sizeof(aNetBuff)); chunkBytes += CurrentRecv; for (int i=0; i<CurrentRecv ; i++) { if (nlCount < 2) { if (aNetBuff[i] == '\r' || aNetBuff[i] == '\n') { ++nlCount; if (NetData.size() > 0) { std::transform(NetData.begin(), NetData.end(), NetData.begin(), ::tolower); if (NetData.find("404 not found") != std::string::npos) { dbg_msg("HttpDownloader", "ERROR 404: '%s' not found...", NetUrl.m_aFile); net_tcp_close(sock); return false; } else if (NetData.find("content-length:") != std::string::npos) { char aFileSize[64]; str_copy(aFileSize, NetData.substr(15).c_str(), sizeof(aFileSize)); str_trim(aFileSize); TotalBytes = atoi(aFileSize); } NetData.clear(); } if (aNetBuff[i] == '\r') ++i; continue; } nlCount = 0; NetData += aNetBuff[i]; } else { if (nlCount == 2) { if (TotalBytes <= 0) { dbg_msg("HttpDownloader", "Error downloading '%s'...", NetUrl.m_aFile); net_tcp_close(sock); return false; } dstFile = io_open(dest, IOFLAG_WRITE); if(!dstFile) { dbg_msg("HttpDownloader", "Error creating '%s'...", dest); net_tcp_close(sock); return false; } ++nlCount; } io_write(dstFile, &aNetBuff[i], 1); TotalRecv++; if (TotalRecv == TotalBytes) break; } } } while (CurrentRecv > 0); net_tcp_close(sock); if (TotalRecv > 0) { io_close(dstFile); return true; } return false; }
void CGameClient::OnPredict() { // store the previous values so we can detect prediction errors CCharacterCore BeforePrevChar = m_PredictedPrevChar; CCharacterCore BeforeChar = m_PredictedChar; // we can't predict without our own id or own character if(m_Snap.m_LocalClientID == -1 || !m_Snap.m_aCharacters[m_Snap.m_LocalClientID].m_Active) return; // don't predict anything if we are paused if(m_Snap.m_pGameInfoObj && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) { if(m_Snap.m_pLocalCharacter) m_PredictedChar.Read(m_Snap.m_pLocalCharacter); if(m_Snap.m_pLocalPrevCharacter) m_PredictedPrevChar.Read(m_Snap.m_pLocalPrevCharacter); return; } // repredict character CWorldCore World; World.m_Tuning = m_Tuning; // search for players for(int i = 0; i < MAX_CLIENTS; i++) { if(!m_Snap.m_aCharacters[i].m_Active) continue; g_GameClient.m_aClients[i].m_Predicted.Init(&World, Collision()); World.m_apCharacters[i] = &g_GameClient.m_aClients[i].m_Predicted; g_GameClient.m_aClients[i].m_Predicted.Read(&m_Snap.m_aCharacters[i].m_Cur); } // predict for(int Tick = Client()->GameTick()+1; Tick <= Client()->PredGameTick(); Tick++) { // fetch the local if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_Snap.m_LocalClientID]) m_PredictedPrevChar = *World.m_apCharacters[m_Snap.m_LocalClientID]; // first calculate where everyone should move for(int c = 0; c < MAX_CLIENTS; c++) { if(!World.m_apCharacters[c]) continue; mem_zero(&World.m_apCharacters[c]->m_Input, sizeof(World.m_apCharacters[c]->m_Input)); if(m_Snap.m_LocalClientID == c) { // apply player input int *pInput = Client()->GetInput(Tick); if(pInput) World.m_apCharacters[c]->m_Input = *((CNetObj_PlayerInput*)pInput); World.m_apCharacters[c]->Tick(true); } else World.m_apCharacters[c]->Tick(false); } // move all players and quantize their data for(int c = 0; c < MAX_CLIENTS; c++) { if(!World.m_apCharacters[c]) continue; World.m_apCharacters[c]->Move(); World.m_apCharacters[c]->Quantize(); } // check if we want to trigger effects if(Tick > m_LastNewPredictedTick) { m_LastNewPredictedTick = Tick; m_NewPredictedTick = true; if(m_Snap.m_LocalClientID != -1 && World.m_apCharacters[m_Snap.m_LocalClientID]) { vec2 Pos = World.m_apCharacters[m_Snap.m_LocalClientID]->m_Pos; int Events = World.m_apCharacters[m_Snap.m_LocalClientID]->m_TriggeredEvents; if(Events&COREEVENT_GROUND_JUMP) g_GameClient.m_pSounds->PlayAndRecord(CSounds::CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, Pos); /*if(events&COREEVENT_AIR_JUMP) { GameClient.effects->air_jump(pos); GameClient.sounds->play_and_record(SOUNDS::CHN_WORLD, SOUND_PLAYER_AIRJUMP, 1.0f, pos); }*/ //if(events&COREEVENT_HOOK_LAUNCH) snd_play_random(CHN_WORLD, SOUND_HOOK_LOOP, 1.0f, pos); //if(events&COREEVENT_HOOK_ATTACH_PLAYER) snd_play_random(CHN_WORLD, SOUND_HOOK_ATTACH_PLAYER, 1.0f, pos); if(Events&COREEVENT_HOOK_ATTACH_GROUND) g_GameClient.m_pSounds->PlayAndRecord(CSounds::CHN_WORLD, SOUND_HOOK_ATTACH_GROUND, 1.0f, Pos); if(Events&COREEVENT_HOOK_HIT_NOHOOK) g_GameClient.m_pSounds->PlayAndRecord(CSounds::CHN_WORLD, SOUND_HOOK_NOATTACH, 1.0f, Pos); //if(events&COREEVENT_HOOK_RETRACT) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos); } } if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_Snap.m_LocalClientID]) m_PredictedChar = *World.m_apCharacters[m_Snap.m_LocalClientID]; } if(g_Config.m_Debug && g_Config.m_ClPredict && m_PredictedTick == Client()->PredGameTick()) { CNetObj_CharacterCore Before = {0}, Now = {0}, BeforePrev = {0}, NowPrev = {0}; BeforeChar.Write(&Before); BeforePrevChar.Write(&BeforePrev); m_PredictedChar.Write(&Now); m_PredictedPrevChar.Write(&NowPrev); if(mem_comp(&Before, &Now, sizeof(CNetObj_CharacterCore)) != 0) { Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "prediction error"); for(unsigned i = 0; i < sizeof(CNetObj_CharacterCore)/sizeof(int); i++) if(((int *)&Before)[i] != ((int *)&Now)[i]) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), " %d %d %d (%d %d)", i, ((int *)&Before)[i], ((int *)&Now)[i], ((int *)&BeforePrev)[i], ((int *)&NowPrev)[i]); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", aBuf); } } } m_PredictedTick = Client()->PredGameTick(); }
CBinds::CBinds() { mem_zero(m_aaKeyBindings, sizeof(m_aaKeyBindings)); m_SpecialBinds.m_pBinds = this; }
static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths) { PROFILER_CPU_TIMESLICE("NVG backend renderFill"); GLNVGcontext* gl = (GLNVGcontext*)uptr; GLNVGcall* call = glnvg__allocCall(gl); GLNVGfragUniforms* frag; GLuint maxverts, offset; if (call == NULL) return; call->type = GLNVG_FILL; call->pathOffset = glnvg__allocPaths(gl, npaths); if (call->pathOffset == -1) goto error; call->pathCount = npaths; call->image = paint->image; if (npaths == 1 && paths[0].convex) call->type = GLNVG_CONVEXFILL; // Allocate vertices for all the paths. maxverts = glnvg__maxVertCount(paths, npaths) + 6; NVGvertex* vtx = gfx::frameAllocVertices<NVGvertex>(maxverts, &offset); if (!vtx) goto error; for (int i = 0; i < npaths; i++) { GLNVGpath* copy = &gl->paths[call->pathOffset + i]; const NVGpath* path = &paths[i]; mem_zero(copy); if (path->nfill > 0) { copy->fillOffset = offset; copy->fillCount = path->nfill; mem_copy(vtx, path->fill, sizeof(NVGvertex) * path->nfill); offset += path->nfill; vtx += path->nfill; } if (path->nstroke > 0) { copy->strokeOffset = offset; copy->strokeCount = path->nstroke; mem_copy(vtx, path->stroke, sizeof(NVGvertex) * path->nstroke); offset += path->nstroke; vtx += path->nstroke; } } // Quad call->triangleOffset = offset; call->triangleCount = 6; *vtx++ = {bounds[0], bounds[3], 0.5f, 1.0f}; *vtx++ = {bounds[2], bounds[3], 0.5f, 1.0f}; *vtx++ = {bounds[2], bounds[1], 0.5f, 1.0f}; *vtx++ = {bounds[0], bounds[3], 0.5f, 1.0f}; *vtx++ = {bounds[2], bounds[1], 0.5f, 1.0f}; *vtx++ = {bounds[0], bounds[1], 0.5f, 1.0f}; gfx::dynbufAlignMem(gfx::caps.uboAlignment, &call->uniformOffset); // Setup uniforms for draw calls if (call->type == GLNVG_FILL) { // Simple shader for stencil frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; mem_zero(frag); frag->strokeThr = -1.0f; frag->type = NSVG_SHADER_SIMPLE; // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, fringe, fringe, -1.0f); } else { // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, fringe, fringe, -1.0f); } return; error: // We get here if call alloc was ok, but something else is not. // Roll back the last call to prevent drawing it. if (gl->ncalls > 0) gl->ncalls--; }
void CCharacter::TickDefered() { // advance the dummy { CWorldCore TempWorld; m_ReckoningCore.Init(&TempWorld, GameServer()->Collision()); m_ReckoningCore.Tick(false); m_ReckoningCore.Move(); m_ReckoningCore.Quantize(); } //lastsentcore vec2 StartPos = m_Core.m_Pos; vec2 StartVel = m_Core.m_Vel; bool StuckBefore = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); m_Core.Move(); bool StuckAfterMove = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); m_Core.Quantize(); bool StuckAfterQuant = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); m_Pos = m_Core.m_Pos; if(!StuckBefore && (StuckAfterMove || StuckAfterQuant)) { dbg_msg("char_core", "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x", StuckBefore, StuckAfterMove, StuckAfterQuant, StartPos.x, StartPos.y, StartVel.x, StartVel.y, *((unsigned *)&StartPos.x), *((unsigned *)&StartPos.y), *((unsigned *)&StartVel.x), *((unsigned *)&StartVel.y)); } int Events = m_Core.m_TriggeredEvents; int Mask = CmaskAllExceptOne(m_pPlayer->GetCID()); if(Events&COREEVENT_GROUND_JUMP) GameServer()->CreateSound(m_Pos, SOUND_PLAYER_JUMP, Mask); if(Events&COREEVENT_HOOK_ATTACH_PLAYER) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_PLAYER, CmaskAll()); if(Events&COREEVENT_HOOK_ATTACH_GROUND) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_GROUND, Mask); if(Events&COREEVENT_HOOK_HIT_NOHOOK) GameServer()->CreateSound(m_Pos, SOUND_HOOK_NOATTACH, Mask); if(m_pPlayer->GetTeam() == -1) { m_Pos.x = m_Input.m_TargetX; m_Pos.y = m_Input.m_TargetY; } // update the m_SendCore if needed { CNetObj_Character Predicted; CNetObj_Character Current; mem_zero(&Predicted, sizeof(Predicted)); mem_zero(&Current, sizeof(Current)); m_ReckoningCore.Write(&Predicted); m_Core.Write(&Current); // only allow dead reackoning for a top of 3 seconds if(m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0) { m_ReckoningTick = Server()->Tick(); m_SendCore = m_Core; m_ReckoningCore = m_Core; } } }
int CControls::SnapInput(int *pData, int *pPredictionData) { static int64 LastSendTime = 0; bool Send = false; // update player state if(m_pClient->m_pChat->IsActive()) m_InputData.m_PlayerFlags = PLAYERFLAG_CHATTING; //else if(m_pClient->m_pMenus->IsActive()) //m_InputData.m_PlayerFlags = PLAYERFLAG_IN_MENU; else m_InputData.m_PlayerFlags = PLAYERFLAG_PLAYING; if(m_pClient->m_pScoreboard->Active() || m_pClient->m_UpdateScoreboard) m_InputData.m_PlayerFlags |= PLAYERFLAG_SCOREBOARD; m_pClient->m_UpdateScoreboard = false; if(m_LastData.m_PlayerFlags != m_InputData.m_PlayerFlags) Send = true; m_LastData.m_PlayerFlags = m_InputData.m_PlayerFlags; // we freeze the input if chat or menu is activated if(!(m_InputData.m_PlayerFlags&PLAYERFLAG_PLAYING)) { OnReset(); mem_copy(pData, &m_InputData, sizeof(m_InputData)); // send once a second just to be sure if(time_get() > LastSendTime + time_freq()) Send = true; } else { m_InputData.m_TargetX = (int)m_MousePos.x; m_InputData.m_TargetY = (int)m_MousePos.y; if(!m_InputData.m_TargetX && !m_InputData.m_TargetY) { m_InputData.m_TargetX = 1; m_MousePos.x = 1; } // set direction m_InputData.m_Direction = 0; if(m_InputDirectionLeft && !m_InputDirectionRight) m_InputData.m_Direction = -1; if(!m_InputDirectionLeft && m_InputDirectionRight) m_InputData.m_Direction = 1; // stress testing if(g_Config.m_DbgStress) { float t = Client()->LocalTime(); mem_zero(&m_InputData, sizeof(m_InputData)); m_InputData.m_Direction = ((int)t/2)&1; m_InputData.m_Jump = ((int)t); m_InputData.m_Fire = ((int)(t*10)); m_InputData.m_Hook = ((int)(t*2))&1; m_InputData.m_WantedWeapon = ((int)t)%NUM_WEAPONS; m_InputData.m_TargetX = (int)(sinf(t*3)*100.0f); m_InputData.m_TargetY = (int)(cosf(t*3)*100.0f); } m_PredictionData = m_InputData; if (m_pClient->m_pLuaBinding) //make sure that we have this class { //Lua m_pClient->m_pLuaBinding->m_ControlDirectionPre = m_InputData.m_Direction; m_pClient->m_pLuaBinding->m_ControlFirePre = m_InputData.m_Fire; m_pClient->m_pLuaBinding->m_ControlJumpPre = m_InputData.m_Jump; m_pClient->m_pLuaBinding->m_ControlHookPre = m_InputData.m_Hook; m_pClient->m_pLuaBinding->m_ControlWeaponPre = m_InputData.m_WantedWeapon; m_pClient->m_pLuaBinding->m_ControlTargetXPre = m_InputData.m_TargetX; m_pClient->m_pLuaBinding->m_ControlTargetYPre = m_InputData.m_TargetY; int EventID = m_pClient->m_pLua->m_pEventListener->CreateEventStack(); m_pClient->m_pLua->m_pEventListener->OnEvent("OnControlChange"); if (m_pClient->m_pLuaBinding->m_ControlDirectionIsSet) { m_InputData.m_Direction = m_pClient->m_pLuaBinding->m_ControlDirection; } if (m_pClient->m_pLuaBinding->m_ControlFireIsSet) { m_InputData.m_Fire = m_pClient->m_pLuaBinding->m_ControlFire; } if (m_pClient->m_pLuaBinding->m_ControlHookIsSet) { m_InputData.m_Hook = m_pClient->m_pLuaBinding->m_ControlHook; } if (m_pClient->m_pLuaBinding->m_ControlJumpIsSet) { m_InputData.m_Jump = m_pClient->m_pLuaBinding->m_ControlJump; } if (m_pClient->m_pLuaBinding->m_ControlWeaponIsSet) { m_InputData.m_WantedWeapon = m_pClient->m_pLuaBinding->m_ControlWeapon; } if (m_pClient->m_pLuaBinding->m_ControlTargetXIsSet) { m_InputData.m_TargetX = m_pClient->m_pLuaBinding->m_ControlTargetX; } if (m_pClient->m_pLuaBinding->m_ControlTargetYIsSet) { m_InputData.m_TargetY = m_pClient->m_pLuaBinding->m_ControlTargetY; } if (m_pClient->m_pLuaBinding->m_ControlDirectionPredictedIsSet) { m_PredictionData.m_Direction = m_pClient->m_pLuaBinding->m_ControlDirectionPredicted; } if (m_pClient->m_pLuaBinding->m_ControlFirePredictedIsSet) { m_PredictionData.m_Fire = m_pClient->m_pLuaBinding->m_ControlFirePredicted; } if (m_pClient->m_pLuaBinding->m_ControlHookPredictedIsSet) { m_PredictionData.m_Hook = m_pClient->m_pLuaBinding->m_ControlHookPredicted; } if (m_pClient->m_pLuaBinding->m_ControlJumpPredictedIsSet) { m_PredictionData.m_Jump = m_pClient->m_pLuaBinding->m_ControlJumpPredicted; } if (m_pClient->m_pLuaBinding->m_ControlWeaponPredictedIsSet) { m_PredictionData.m_WantedWeapon = m_pClient->m_pLuaBinding->m_ControlWeaponPredicted; } if (m_pClient->m_pLuaBinding->m_ControlTargetXPredictedIsSet) { m_PredictionData.m_TargetX = m_pClient->m_pLuaBinding->m_ControlTargetXPredicted; } if (m_pClient->m_pLuaBinding->m_ControlTargetYPredictedIsSet) { m_PredictionData.m_TargetY = m_pClient->m_pLuaBinding->m_ControlTargetYPredicted; } } // check if we need to send input if(m_InputData.m_Direction != m_LastData.m_Direction) Send = true; else if(m_InputData.m_Jump != m_LastData.m_Jump) Send = true; else if(m_InputData.m_Fire != m_LastData.m_Fire) Send = true; else if(m_InputData.m_Hook != m_LastData.m_Hook) Send = true; else if(m_InputData.m_WantedWeapon != m_LastData.m_WantedWeapon) Send = true; else if(m_InputData.m_NextWeapon != m_LastData.m_NextWeapon) Send = true; else if(m_InputData.m_PrevWeapon != m_LastData.m_PrevWeapon) Send = true; // send at at least 10hz if(time_get() > LastSendTime + time_freq()/25) Send = true; } // copy and return size m_LastData = m_InputData; if(!Send) return 0; LastSendTime = time_get(); mem_copy(pData, &m_InputData, sizeof(m_InputData)); mem_copy(pPredictionData, &m_PredictionData, sizeof(m_PredictionData)); return sizeof(m_InputData); }
virtual void SetDefault() { mem_zero(m_aMasterServers, sizeof(m_aMasterServers)); for(int i = 0; i < MAX_MASTERSERVERS; i++) str_format(m_aMasterServers[i].m_aHostname, sizeof(m_aMasterServers[i].m_aHostname), "master%d.teeworlds.com", i+1); }
void CServerBrowser::Update(bool ForceResort) { int64 Timeout = time_freq(); int64 Now = time_get(); int Count; CServerEntry *pEntry, *pNext; // do server list requests if(m_NeedRefresh && !m_pMasterServer->IsRefreshing()) { NETADDR Addr; CNetChunk Packet; int i; m_NeedRefresh = 0; mem_zero(&Packet, sizeof(Packet)); Packet.m_ClientID = -1; Packet.m_Flags = NETSENDFLAG_CONNLESS; Packet.m_DataSize = sizeof(SERVERBROWSE_GETLIST); Packet.m_pData = SERVERBROWSE_GETLIST; for(i = 0; i < IMasterServer::MAX_MASTERSERVERS; i++) { if(!m_pMasterServer->IsValid(i)) continue; Addr = m_pMasterServer->GetAddr(i); Packet.m_Address = Addr; m_pNetClient->Send(&Packet); } if(g_Config.m_Debug) m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "requesting server list"); } // do timeouts pEntry = m_pFirstReqServer; while(1) { if(!pEntry) // no more entries break; pNext = pEntry->m_pNextReq; if(pEntry->m_RequestTime && pEntry->m_RequestTime+Timeout < Now) { // timeout RemoveRequest(pEntry); } pEntry = pNext; } // do timeouts pEntry = m_pFirstReqServer; Count = 0; while(1) { if(!pEntry) // no more entries break; // no more then 10 concurrent requests if(Count == g_Config.m_BrMaxRequests) break; if(pEntry->m_RequestTime == 0) RequestImpl(pEntry->m_Addr, pEntry); Count++; pEntry = pEntry->m_pNextReq; } // check if we need to resort if(m_Sorthash != SortHash() || ForceResort) Sort(); }
int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr) { int64 Now = time_get(); // check if resend is requested if(pPacket->m_Flags&NET_PACKETFLAG_RESEND) Resend(); // if(pPacket->m_Flags&NET_PACKETFLAG_CONTROL) { int CtrlMsg = pPacket->m_aChunkData[0]; if(CtrlMsg == NET_CTRLMSG_CLOSE) { if(net_addr_comp(&m_PeerAddr, pAddr) == 0) { m_State = NET_CONNSTATE_ERROR; m_RemoteClosed = 1; char Str[128] = {0}; if(pPacket->m_DataSize > 1) { // make sure to sanitize the error string form the other party if(pPacket->m_DataSize < 128) str_copy(Str, (char *)&pPacket->m_aChunkData[1], pPacket->m_DataSize); else str_copy(Str, (char *)&pPacket->m_aChunkData[1], sizeof(Str)); str_sanitize_strong(Str); } if(!m_BlockCloseMsg) { // set the error string SetError(Str); } if(g_Config.m_Debug) dbg_msg("conn", "closed reason='%s'", Str); } return 0; } else { if(State() == NET_CONNSTATE_OFFLINE) { if(CtrlMsg == NET_CTRLMSG_CONNECT) { // send response and init connection Reset(); m_State = NET_CONNSTATE_PENDING; m_PeerAddr = *pAddr; mem_zero(m_ErrorString, sizeof(m_ErrorString)); m_LastSendTime = Now; m_LastRecvTime = Now; m_LastUpdateTime = Now; SendControl(NET_CTRLMSG_CONNECTACCEPT, 0, 0); if(g_Config.m_Debug) dbg_msg("connection", "got connection, sending connect+accept"); } } else if(State() == NET_CONNSTATE_CONNECT) { // connection made if(CtrlMsg == NET_CTRLMSG_CONNECTACCEPT) { m_LastRecvTime = Now; SendControl(NET_CTRLMSG_ACCEPT, 0, 0); m_State = NET_CONNSTATE_ONLINE; if(g_Config.m_Debug) dbg_msg("connection", "got connect+accept, sending accept. connection online"); } } } } else { if(State() == NET_CONNSTATE_PENDING) { m_LastRecvTime = Now; m_State = NET_CONNSTATE_ONLINE; if(g_Config.m_Debug) dbg_msg("connection", "connecting online"); } } if(State() == NET_CONNSTATE_ONLINE) { m_LastRecvTime = Now; AckChunks(pPacket->m_Ack); } return 1; }
void CGameClient::OnNewSnapshot() { // clear out the invalid pointers mem_zero(&m_Snap, sizeof(m_Snap)); // secure snapshot { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int Index = 0; Index < Num; Index++) { IClient::CSnapItem Item; void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item); if(m_NetObjHandler.ValidateObj(Item.m_Type, pData, Item.m_DataSize) != 0) { if(g_Config.m_Debug) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "invalidated index=%d type=%d (%s) size=%d id=%d", Index, Item.m_Type, m_NetObjHandler.GetObjName(Item.m_Type), Item.m_DataSize, Item.m_ID); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); } Client()->SnapInvalidateItem(IClient::SNAP_CURRENT, Index); } } } ProcessEvents(); if(g_Config.m_DbgStress) { if((Client()->GameTick()%100) == 0) { char aMessage[64]; int MsgLen = rand()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) aMessage[i] = 'a'+(rand()%('z'-'a')); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; Msg.m_Team = rand()&1; Msg.m_pMessage = aMessage; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } } CTuningParams StandardTuning; if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { m_Tuning = StandardTuning; mem_zero(&m_GameInfo, sizeof(m_GameInfo)); } // go trough all the items in the snapshot and gather the info we want { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int i = 0; i < Num; i++) { IClient::CSnapItem Item; const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); // demo items if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { if(Item.m_Type == NETOBJTYPE_DE_CLIENTINFO) { const CNetObj_De_ClientInfo *pInfo = (const CNetObj_De_ClientInfo *)pData; int ClientID = Item.m_ID; CClientData *pClient = &m_aClients[ClientID]; if(pInfo->m_Local) m_LocalClientID = ClientID; pClient->m_Active = true; pClient->m_Team = pInfo->m_Team; IntsToStr(pInfo->m_aName, 4, pClient->m_aName); IntsToStr(pInfo->m_aClan, 3, pClient->m_aClan); pClient->m_Country = pInfo->m_Country; for(int p = 0; p < NUM_SKINPARTS; p++) { IntsToStr(pInfo->m_aaSkinPartNames[p], 6, pClient->m_aaSkinPartNames[p]); pClient->m_aUseCustomColors[p] = pInfo->m_aUseCustomColors[p]; pClient->m_aSkinPartColors[p] = pInfo->m_aSkinPartColors[p]; } m_GameInfo.m_NumPlayers++; // calculate team-balance if(pClient->m_Team != TEAM_SPECTATORS) m_GameInfo.m_aTeamSize[pClient->m_Team]++; } else if(Item.m_Type == NETOBJTYPE_DE_GAMEINFO) { const CNetObj_De_GameInfo *pInfo = (const CNetObj_De_GameInfo *)pData; m_GameInfo.m_GameFlags = pInfo->m_GameFlags; m_GameInfo.m_ScoreLimit = pInfo->m_ScoreLimit; m_GameInfo.m_TimeLimit = pInfo->m_TimeLimit; m_GameInfo.m_MatchNum = pInfo->m_MatchNum; m_GameInfo.m_MatchCurrent = pInfo->m_MatchCurrent; } else if(Item.m_Type == NETOBJTYPE_DE_TUNEPARAMS) { const CNetObj_De_TuneParams *pInfo = (const CNetObj_De_TuneParams *)pData; mem_copy(&m_Tuning, pInfo->m_aTuneParams, sizeof(m_Tuning)); m_ServerMode = SERVERMODE_PURE; } } // network items if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; int ClientID = Item.m_ID; if(m_aClients[ClientID].m_Active) { m_Snap.m_paPlayerInfos[ClientID] = pInfo; m_Snap.m_aInfoByScore[ClientID].m_pPlayerInfo = pInfo; m_Snap.m_aInfoByScore[ClientID].m_ClientID = ClientID; if(m_LocalClientID == ClientID) { m_Snap.m_pLocalInfo = pInfo; if(m_aClients[ClientID].m_Team == TEAM_SPECTATORS) { m_Snap.m_SpecInfo.m_Active = true; m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } } } } else if(Item.m_Type == NETOBJTYPE_CHARACTER) { const void *pOld = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, Item.m_ID); m_Snap.m_aCharacters[Item.m_ID].m_Cur = *((const CNetObj_Character *)pData); // clamp ammo count for non ninja weapon if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Weapon != WEAPON_NINJA) m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_AmmoCount = clamp(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_AmmoCount, 0, 10); if(pOld) { m_Snap.m_aCharacters[Item.m_ID].m_Active = true; m_Snap.m_aCharacters[Item.m_ID].m_Prev = *((const CNetObj_Character *)pOld); if(m_Snap.m_aCharacters[Item.m_ID].m_Prev.m_Tick) EvolveCharacter(&m_Snap.m_aCharacters[Item.m_ID].m_Prev, Client()->PrevGameTick()); if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Tick) EvolveCharacter(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, Client()->GameTick()); } if(Item.m_ID != m_LocalClientID || Client()->State() == IClient::STATE_DEMOPLAYBACK) ProcessTriggeredEvents(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_TriggeredEvents, vec2(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_X, m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Y)); } else if(Item.m_Type == NETOBJTYPE_SPECTATORINFO) { m_Snap.m_pSpectatorInfo = (const CNetObj_SpectatorInfo *)pData; m_Snap.m_pPrevSpectatorInfo = (const CNetObj_SpectatorInfo *)Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_SPECTATORINFO, Item.m_ID); m_Snap.m_SpecInfo.m_Active = true; m_Snap.m_SpecInfo.m_SpectatorID = m_Snap.m_pSpectatorInfo->m_SpectatorID; } else if(Item.m_Type == NETOBJTYPE_GAMEDATA) { m_Snap.m_pGameData = (const CNetObj_GameData *)pData; static bool s_GameOver = 0; if(!s_GameOver && m_Snap.m_pGameData->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) OnGameOver(); else if(s_GameOver && !(m_Snap.m_pGameData->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) OnStartGame(); s_GameOver = m_Snap.m_pGameData->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER; } else if(Item.m_Type == NETOBJTYPE_GAMEDATATEAM) { m_Snap.m_pGameDataTeam = (const CNetObj_GameDataTeam *)pData; } else if(Item.m_Type == NETOBJTYPE_GAMEDATAFLAG) { m_Snap.m_pGameDataFlag = (const CNetObj_GameDataFlag *)pData; m_Snap.m_GameDataFlagSnapID = Item.m_ID; } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; } } // setup local pointers if(m_LocalClientID >= 0) { CSnapState::CCharacterInfo *c = &m_Snap.m_aCharacters[m_LocalClientID]; if(c->m_Active) { m_Snap.m_pLocalCharacter = &c->m_Cur; m_Snap.m_pLocalPrevCharacter = &c->m_Prev; m_LocalCharacterPos = vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y); } else if(Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, m_LocalClientID)) { // player died m_pControls->OnPlayerDeath(); } } else { m_Snap.m_SpecInfo.m_Active = true; if(Client()->State() == IClient::STATE_DEMOPLAYBACK && DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER && m_DemoSpecID != SPEC_FREEVIEW && m_Snap.m_aCharacters[m_DemoSpecID].m_Active) m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID; else m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } // sort player infos by score for(int k = 0; k < MAX_CLIENTS-1; k++) // ffs, bubblesort { for(int i = 0; i < MAX_CLIENTS-k-1; i++) { if(m_Snap.m_aInfoByScore[i+1].m_pPlayerInfo && (!m_Snap.m_aInfoByScore[i].m_pPlayerInfo || m_Snap.m_aInfoByScore[i].m_pPlayerInfo->m_Score < m_Snap.m_aInfoByScore[i+1].m_pPlayerInfo->m_Score)) { CPlayerInfoItem Tmp = m_Snap.m_aInfoByScore[i]; m_Snap.m_aInfoByScore[i] = m_Snap.m_aInfoByScore[i+1]; m_Snap.m_aInfoByScore[i+1] = Tmp; } } } // calc some player stats for(int i = 0; i < MAX_CLIENTS; ++i) { if(!m_Snap.m_paPlayerInfos[i]) continue; // count not ready players if((m_Snap.m_pGameData->m_GameStateFlags&(GAMESTATEFLAG_STARTCOUNTDOWN|GAMESTATEFLAG_PAUSED|GAMESTATEFLAG_WARMUP)) && m_Snap.m_pGameData->m_GameStateEndTick == 0 && m_aClients[i].m_Team != TEAM_SPECTATORS && !(m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_READY)) m_Snap.m_NotReadyCount++; // count alive players per team if((m_GameInfo.m_GameFlags&GAMEFLAG_SURVIVAL) && m_aClients[i].m_Team != TEAM_SPECTATORS && !(m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_DEAD)) m_Snap.m_AliveCount[m_aClients[i].m_Team]++; } if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { for(int i = 0; i < MAX_CLIENTS; ++i) { if(m_aClients[i].m_Active) m_aClients[i].UpdateRenderInfo(this, true); } } CServerInfo CurrentServerInfo; Client()->GetServerInfo(&CurrentServerInfo); if(CurrentServerInfo.m_aGameType[0] != '0') { if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0 && str_comp(CurrentServerInfo.m_aGameType, "LMS") != 0 && str_comp(CurrentServerInfo.m_aGameType, "SUR") != 0) m_ServerMode = SERVERMODE_MOD; else if(mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) == 0) m_ServerMode = SERVERMODE_PURE; else m_ServerMode = SERVERMODE_PUREMOD; } }
void CNetConnection::ResetStats() { mem_zero(&m_Stats, sizeof(m_Stats)); }
int CMain::HandleMessage(int ClientNetID, char *pMessage) { CClient *pClient = ClientNet(ClientNetID); if(!pClient) return true; if(str_comp_num(pMessage, "update", sizeof("update")-1) == 0) { char *pData = str_skip_whitespaces(&pMessage[sizeof("update")-1]); // parse json data json_settings JsonSettings; mem_zero(&JsonSettings, sizeof(JsonSettings)); char aError[256]; json_value *pJsonData = json_parse_ex(&JsonSettings, pData, strlen(pData), aError); if(!pJsonData) { dbg_msg("main", "JSON Error: %s", aError); if(pClient->m_Stats.m_Pong) m_Server.Network()->Send(ClientNetID, "1"); return 1; } // extract data const json_value &rStart = (*pJsonData); if(rStart["uptime"].type) pClient->m_Stats.m_Uptime = rStart["uptime"].u.integer; if(rStart["load"].type) pClient->m_Stats.m_Load = rStart["load"].u.dbl; if(rStart["network_rx"].type) pClient->m_Stats.m_NetworkRx = rStart["network_rx"].u.integer; if(rStart["network_tx"].type) pClient->m_Stats.m_NetworkTx = rStart["network_tx"].u.integer; if(rStart["memory_total"].type) pClient->m_Stats.m_MemTotal = rStart["memory_total"].u.integer; if(rStart["memory_used"].type) pClient->m_Stats.m_MemUsed = rStart["memory_used"].u.integer; if(rStart["hdd_total"].type) pClient->m_Stats.m_HDDTotal = rStart["hdd_total"].u.integer; if(rStart["hdd_used"].type) pClient->m_Stats.m_HDDUsed = rStart["hdd_used"].u.integer; if(rStart["cpu"].type) pClient->m_Stats.m_CPU = rStart["cpu"].u.dbl; if(rStart["online4"].type && pClient->m_ClientNetType == NETTYPE_IPV6) pClient->m_Stats.m_Online4 = rStart["online4"].u.boolean; if(rStart["online6"].type && pClient->m_ClientNetType == NETTYPE_IPV4) pClient->m_Stats.m_Online6 = rStart["online6"].u.boolean; if(m_Config.m_Verbose) { if(rStart["online4"].type) dbg_msg("main", "Online4: %s\nUptime: %" PRId64 "\nLoad: %lf\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %lf\n", rStart["online4"].u.boolean ? "true" : "false", pClient->m_Stats.m_Uptime, pClient->m_Stats.m_Load, pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU); else if(rStart["online6"].type) dbg_msg("main", "Online6: %s\nUptime: %" PRId64 "\nLoad: %lf\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %lf\n", rStart["online6"].u.boolean ? "true" : "false", pClient->m_Stats.m_Uptime, pClient->m_Stats.m_Load, pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU); else dbg_msg("main", "Uptime: %" PRId64 "\nLoad: %lf\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %lf\n", pClient->m_Stats.m_Uptime, pClient->m_Stats.m_Load, pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU); } // clean up json_value_free(pJsonData); if(pClient->m_Stats.m_Pong) m_Server.Network()->Send(ClientNetID, "0"); return 0; } else if(str_comp_num(pMessage, "pong", sizeof("pong")-1) == 0) { char *pData = str_skip_whitespaces(&pMessage[sizeof("pong")-1]); if(!str_comp(pData, "0") || !str_comp(pData, "off")) pClient->m_Stats.m_Pong = false; else if(!str_comp(pData, "1") || !str_comp(pData, "on")) pClient->m_Stats.m_Pong = true; return 0; } if(pClient->m_Stats.m_Pong) m_Server.Network()->Send(ClientNetID, "1"); return 1; }
void CCollision::Init(class CLayers *pLayers) { if(m_pLayers) m_pLayers->Dest(); Dest(); m_NumSwitchers = 0; m_pLayers = pLayers; m_Width = m_pLayers->GameLayer()->m_Width; m_Height = m_pLayers->GameLayer()->m_Height; m_pTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data)); if(m_pLayers->TeleLayer()) { unsigned int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->TeleLayer()->m_Tele); if (Size >= m_Width*m_Height*sizeof(CTeleTile)) m_pTele = static_cast<CTeleTile *>(m_pLayers->Map()->GetData(m_pLayers->TeleLayer()->m_Tele)); } if(m_pLayers->SpeedupLayer()) { unsigned int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->SpeedupLayer()->m_Speedup); if (Size >= m_Width*m_Height*sizeof(CSpeedupTile)) m_pSpeedup = static_cast<CSpeedupTile *>(m_pLayers->Map()->GetData(m_pLayers->SpeedupLayer()->m_Speedup)); } if(m_pLayers->SwitchLayer()) { unsigned int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->SwitchLayer()->m_Switch); if (Size >= m_Width*m_Height*sizeof(CSwitchTile)) m_pSwitch = static_cast<CSwitchTile *>(m_pLayers->Map()->GetData(m_pLayers->SwitchLayer()->m_Switch)); m_pDoor = new CDoorTile[m_Width*m_Height]; mem_zero(m_pDoor, m_Width * m_Height * sizeof(CDoorTile)); } else { m_pDoor = 0; m_pSwitchers = 0; } if(m_pLayers->TuneLayer()) { unsigned int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->TuneLayer()->m_Tune); if (Size >= m_Width*m_Height*sizeof(CTuneTile)) m_pTune = static_cast<CTuneTile *>(m_pLayers->Map()->GetData(m_pLayers->TuneLayer()->m_Tune)); } if(m_pLayers->FrontLayer()) { unsigned int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->FrontLayer()->m_Front); if (Size >= m_Width*m_Height*sizeof(CTile)) m_pFront = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->FrontLayer()->m_Front)); } for(int i = 0; i < m_Width*m_Height; i++) { int Index; if(m_pSwitch) { if(m_pSwitch[i].m_Number > m_NumSwitchers) m_NumSwitchers = m_pSwitch[i].m_Number; if(m_pSwitch[i].m_Number) m_pDoor[i].m_Number = m_pSwitch[i].m_Number; else m_pDoor[i].m_Number = 0; Index = m_pSwitch[i].m_Type; if(Index <= TILE_NPH_START) { if(Index >= TILE_JUMP && Index <= TILE_BONUS) m_pSwitch[i].m_Type = Index; else m_pSwitch[i].m_Type = 0; } } if(m_pFront) { Index = m_pFront[i].m_Index; if(Index <= TILE_NPH_START) { switch(Index) { case TILE_DEATH: m_pFront[i].m_Index = COLFLAG_DEATH; break; case TILE_SOLID: m_pFront[i].m_Index = 0; break; case TILE_NOHOOK: m_pFront[i].m_Index = 0; break; case TILE_NOLASER: m_pFront[i].m_Index = TILE_NOLASER; break; default: m_pFront[i].m_Index = 0; } // DDRace tiles if(Index == TILE_THROUGH || Index == TILE_FREEZE || (Index >= TILE_UNFREEZE && Index <= TILE_DUNFREEZE) || (Index >= TILE_WALLJUMP && Index <= TILE_SOLO_END) || (Index >= TILE_REFILL_JUMPS && Index <= TILE_STOPA) || Index == TILE_CP || Index == TILE_CP_F || (Index >= TILE_OLDLASER && Index <= TILE_UNLOCK_TEAM) || (Index >= TILE_NPC_END && Index <= TILE_NPH_END) || (Index >= TILE_NPC_START && Index <= TILE_NPH_START)) m_pFront[i].m_Index = Index; } } Index = m_pTiles[i].m_Index; if(Index <= TILE_NPH_START) { switch(Index) { case TILE_DEATH: m_pTiles[i].m_Index = COLFLAG_DEATH; break; case TILE_SOLID: m_pTiles[i].m_Index = COLFLAG_SOLID; break; case TILE_NOHOOK: m_pTiles[i].m_Index = COLFLAG_SOLID|COLFLAG_NOHOOK; break; case TILE_NOLASER: m_pTiles[i].m_Index = TILE_NOLASER; break; default: m_pTiles[i].m_Index = 0; } // DDRace tiles if(Index == TILE_THROUGH || Index == TILE_FREEZE || (Index >= TILE_UNFREEZE && Index <= TILE_DUNFREEZE) || (Index >= TILE_WALLJUMP && Index <= TILE_SOLO_END) || (Index >= TILE_REFILL_JUMPS && Index <= TILE_STOPA) || Index == TILE_CP || Index == TILE_CP_F || (Index >= TILE_OLDLASER && Index <= TILE_UNLOCK_TEAM) || (Index >= TILE_NPC_END && Index <= TILE_NPH_END) || (Index >= TILE_NPC_START && Index <= TILE_NPH_START)) m_pTiles[i].m_Index = Index; } } if(m_NumSwitchers) { m_pSwitchers = new SSwitchers[m_NumSwitchers+1]; for (int i = 0; i < m_NumSwitchers+1; ++i) { m_pSwitchers[i].m_Initial = true; for (int j = 0; j < MAX_CLIENTS; ++j) { m_pSwitchers[i].m_Status[j] = true; m_pSwitchers[i].m_EndTick[j] = 0; m_pSwitchers[i].m_Type[j] = 0; } } } }