void CGraphics_Threaded::DrawVisualObject(int VisualObjectIDX, float *pColor, char** pOffsets, unsigned int *IndicedVertexDrawNum, size_t NumIndicesOffet) { if(NumIndicesOffet == 0) return; //add the VertexArrays and draw CCommandBuffer::SCommand_RenderVertexArray Cmd; Cmd.m_State = m_State; Cmd.m_IndicesDrawNum = NumIndicesOffet; Cmd.m_VisualObjectIDX = m_VertexArrayIndices[VisualObjectIDX]; mem_copy(&Cmd.m_Color, pColor, sizeof(Cmd.m_Color)); float ScreenZoomRatio = ScreenWidth() / (m_State.m_ScreenBR.x - m_State.m_ScreenTL.x); //the number of pixels we would skip in the fragment shader -- basically the LOD float LODFactor = (64.f / (32.f * ScreenZoomRatio)); //log2 gives us the amount of halving the texture for mipmapping int LOD = (int)log2f(LODFactor); //5 because log2(1024/(2^5)) is 5 -- 2^5 = 32 which would mean 2 pixels per tile index if(LOD > 5) LOD = 5; if(LOD < 0) LOD = 0; Cmd.m_LOD = LOD; void *Data = m_pCommandBuffer->AllocData((sizeof(char*) + sizeof(unsigned int))*NumIndicesOffet); if(Data == 0x0) { // kick command buffer and try again KickCommandBuffer(); void *Data = m_pCommandBuffer->AllocData((sizeof(char*) + sizeof(unsigned int))*NumIndicesOffet); if(Data == 0x0) { dbg_msg("graphics", "failed to allocate data for vertices"); return; } } Cmd.m_pIndicesOffsets = (char**)Data; Cmd.m_pDrawCount = (unsigned int*)(((char*)Data) + (sizeof(char*)*NumIndicesOffet)); // check if we have enough free memory in the commandbuffer if(!m_pCommandBuffer->AddCommand(Cmd)) { // kick command buffer and try again KickCommandBuffer(); Data = m_pCommandBuffer->AllocData((sizeof(char*) + sizeof(unsigned int))*NumIndicesOffet); if(Data == 0x0) { dbg_msg("graphics", "failed to allocate data for vertices"); return; } Cmd.m_pIndicesOffsets = (char**)Data; Cmd.m_pDrawCount = (unsigned int*)(((char*)Data) + (sizeof(char*)*NumIndicesOffet)); if(!m_pCommandBuffer->AddCommand(Cmd)) { dbg_msg("graphics", "failed to allocate memory for render command"); return; } } mem_copy(Cmd.m_pIndicesOffsets, pOffsets, sizeof(char*)*NumIndicesOffet); mem_copy(Cmd.m_pDrawCount, IndicedVertexDrawNum, sizeof(unsigned int)*NumIndicesOffet); //todo max indices group check!! }
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 = GetCountryIndex(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)) 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; } }
void CGraphics_Threaded::FlushVertices() { if(m_NumVertices == 0) return; int NumVerts = m_NumVertices; m_NumVertices = 0; CCommandBuffer::SCommand_Render Cmd; Cmd.m_State = m_State; if(m_Drawing == DRAWING_QUADS) { if(g_Config.m_GfxQuadAsTriangle) { Cmd.m_PrimType = CCommandBuffer::PRIMTYPE_TRIANGLES; Cmd.m_PrimCount = NumVerts/3; } else { Cmd.m_PrimType = CCommandBuffer::PRIMTYPE_QUADS; Cmd.m_PrimCount = NumVerts/4; } } else if(m_Drawing == DRAWING_LINES) { Cmd.m_PrimType = CCommandBuffer::PRIMTYPE_LINES; Cmd.m_PrimCount = NumVerts/2; } else return; Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(sizeof(CCommandBuffer::SVertex)*NumVerts); if(Cmd.m_pVertices == 0x0) { // kick command buffer and try again KickCommandBuffer(); Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(sizeof(CCommandBuffer::SVertex)*NumVerts); if(Cmd.m_pVertices == 0x0) { dbg_msg("graphics", "failed to allocate data for vertices"); return; } } // check if we have enough free memory in the commandbuffer if(!m_pCommandBuffer->AddCommand(Cmd)) { // kick command buffer and try again KickCommandBuffer(); Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(sizeof(CCommandBuffer::SVertex)*NumVerts); if(Cmd.m_pVertices == 0x0) { dbg_msg("graphics", "failed to allocate data for vertices"); return; } if(!m_pCommandBuffer->AddCommand(Cmd)) { dbg_msg("graphics", "failed to allocate memory for render command"); return; } } mem_copy(Cmd.m_pVertices, m_aVertices, sizeof(CCommandBuffer::SVertex)*NumVerts); }
int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int StorageType) { CDataFileReader DataFile; //DATAFILE *df = datafile_load(filename); if(!DataFile.Open(pStorage, pFileName, StorageType)) return 0; Clean(); // check version CMapItemVersion *pItem = (CMapItemVersion *)DataFile.FindItem(MAPITEMTYPE_VERSION, 0); if(!pItem) { // import old map /*MAP old_mapstuff; editor->reset(); editor_load_old(df, this); */ return 0; } else if(pItem->m_Version == 1) { //editor.reset(false); // load map info { CMapItemInfo *pItem = (CMapItemInfo *)DataFile.FindItem(MAPITEMTYPE_INFO, 0); if(pItem && pItem->m_Version == 1) { if(pItem->m_Author > -1) str_copy(m_MapInfo.m_aAuthor, (char *)DataFile.GetData(pItem->m_Author), sizeof(m_MapInfo.m_aAuthor)); if(pItem->m_MapVersion > -1) str_copy(m_MapInfo.m_aVersion, (char *)DataFile.GetData(pItem->m_MapVersion), sizeof(m_MapInfo.m_aVersion)); if(pItem->m_Credits > -1) str_copy(m_MapInfo.m_aCredits, (char *)DataFile.GetData(pItem->m_Credits), sizeof(m_MapInfo.m_aCredits)); if(pItem->m_License > -1) str_copy(m_MapInfo.m_aLicense, (char *)DataFile.GetData(pItem->m_License), sizeof(m_MapInfo.m_aLicense)); } } // load images { int Start, Num; DataFile.GetType( MAPITEMTYPE_IMAGE, &Start, &Num); for(int i = 0; i < Num; i++) { CMapItemImage *pItem = (CMapItemImage *)DataFile.GetItem(Start+i, 0, 0); char *pName = (char *)DataFile.GetData(pItem->m_ImageName); // copy base info CEditorImage *pImg = new CEditorImage(m_pEditor); pImg->m_External = pItem->m_External; if(pItem->m_External) { char aBuf[256]; str_format(aBuf, sizeof(aBuf),"mapres/%s.png", pName); // load external CEditorImage ImgInfo(m_pEditor); if(m_pEditor->Graphics()->LoadPNG(&ImgInfo, aBuf, IStorage::TYPE_ALL)) { *pImg = ImgInfo; pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0); ImgInfo.m_pData = 0; pImg->m_External = 1; } } else { pImg->m_Width = pItem->m_Width; pImg->m_Height = pItem->m_Height; pImg->m_Format = CImageInfo::FORMAT_RGBA; // copy image data void *pData = DataFile.GetData(pItem->m_ImageData); pImg->m_pData = mem_alloc(pImg->m_Width*pImg->m_Height*4, 1); mem_copy(pImg->m_pData, pData, pImg->m_Width*pImg->m_Height*4); pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, CImageInfo::FORMAT_AUTO, 0); } // copy image name if(pName) str_copy(pImg->m_aName, pName, 128); // load auto mapper file pImg->m_AutoMapper.Load(pImg->m_aName); m_lImages.add(pImg); // unload image DataFile.UnloadData(pItem->m_ImageData); DataFile.UnloadData(pItem->m_ImageName); } } // load groups { int LayersStart, LayersNum; DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum); int Start, Num; DataFile.GetType(MAPITEMTYPE_GROUP, &Start, &Num); for(int g = 0; g < Num; g++) { CMapItemGroup *pGItem = (CMapItemGroup *)DataFile.GetItem(Start+g, 0, 0); if(pGItem->m_Version < 1 || pGItem->m_Version > CMapItemGroup::CURRENT_VERSION) continue; CLayerGroup *pGroup = NewGroup(); pGroup->m_ParallaxX = pGItem->m_ParallaxX; pGroup->m_ParallaxY = pGItem->m_ParallaxY; pGroup->m_OffsetX = pGItem->m_OffsetX; pGroup->m_OffsetY = pGItem->m_OffsetY; if(pGItem->m_Version >= 2) { pGroup->m_UseClipping = pGItem->m_UseClipping; pGroup->m_ClipX = pGItem->m_ClipX; pGroup->m_ClipY = pGItem->m_ClipY; pGroup->m_ClipW = pGItem->m_ClipW; pGroup->m_ClipH = pGItem->m_ClipH; } // load group name if(pGItem->m_Version >= 3) IntsToStr(pGItem->m_aName, sizeof(pGroup->m_aName)/sizeof(int), pGroup->m_aName); for(int l = 0; l < pGItem->m_NumLayers; l++) { CLayer *pLayer = 0; CMapItemLayer *pLayerItem = (CMapItemLayer *)DataFile.GetItem(LayersStart+pGItem->m_StartLayer+l, 0, 0); if(!pLayerItem) continue; if(pLayerItem->m_Type == LAYERTYPE_TILES) { CMapItemLayerTilemap *pTilemapItem = (CMapItemLayerTilemap *)pLayerItem; CLayerTiles *pTiles = 0; if(pTilemapItem->m_Flags&TILESLAYERFLAG_PHYSICS) { pTiles = new CLayerPhysics(pTilemapItem->m_Width, pTilemapItem->m_Height); MakePhysicsLayer(pTiles); MakeGameGroup(pGroup); } else if(pTilemapItem->m_Flags&TILESLAYERFLAG_ZONE) { pTiles = new CLayerZone(pTilemapItem->m_Width, pTilemapItem->m_Height); MakeZoneLayer(pTiles); MakeGameGroup(pGroup); } else if(pTilemapItem->m_Flags&TILESLAYERFLAG_ENTITY) { pTiles = new CLayerEntity(pTilemapItem->m_Width, pTilemapItem->m_Height); MakeEntityLayer(pTiles); MakeGameGroup(pGroup); } else { pTiles = new CLayerTiles(pTilemapItem->m_Width, pTilemapItem->m_Height); pTiles->m_pEditor = m_pEditor; pTiles->m_Color = pTilemapItem->m_Color; pTiles->m_ColorEnv = pTilemapItem->m_ColorEnv; pTiles->m_ColorEnvOffset = pTilemapItem->m_ColorEnvOffset; } pLayer = pTiles; pGroup->AddLayer(pTiles); void *pData = DataFile.GetData(pTilemapItem->m_Data); pTiles->m_Image = pTilemapItem->m_Image; pTiles->m_GameFlags = pTilemapItem->m_Flags; // load layer name if(pTilemapItem->m_Version >= 3) { if(pTilemapItem->m_Flags&TILESLAYERFLAG_PHYSICS) str_copy(pTiles->m_aName, "Physics", sizeof(pTiles->m_aName)); else if(pTilemapItem->m_Flags&TILESLAYERFLAG_ZONE) str_copy(pTiles->m_aName, "Zones", sizeof(pTiles->m_aName)); else if(pTilemapItem->m_Flags&TILESLAYERFLAG_ENTITY) str_copy(pTiles->m_aName, "Entities", sizeof(pTiles->m_aName)); else IntsToStr(pTilemapItem->m_aName, sizeof(pTiles->m_aName)/sizeof(int), pTiles->m_aName); } mem_copy(pTiles->m_pTiles, pData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile)); if((pTiles->m_GameFlags & TILESLAYERFLAG_PHYSICS) && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) { for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++) { if(pTiles->m_pTiles[i].m_Index) pTiles->m_pTiles[i].m_Index += ENTITY_OFFSET; } } DataFile.UnloadData(pTilemapItem->m_Data); } else if(pLayerItem->m_Type == LAYERTYPE_QUADS) { CMapItemLayerQuads *pQuadsItem = (CMapItemLayerQuads *)pLayerItem; CLayerQuads *pQuads = new CLayerQuads; pQuads->m_pEditor = m_pEditor; pLayer = pQuads; pQuads->m_Image = pQuadsItem->m_Image; if(pQuads->m_Image < -1 || pQuads->m_Image >= m_lImages.size()) pQuads->m_Image = -1; // load layer name if(pQuadsItem->m_Version >= 2) IntsToStr(pQuadsItem->m_aName, sizeof(pQuads->m_aName)/sizeof(int), pQuads->m_aName); void *pData = DataFile.GetDataSwapped(pQuadsItem->m_Data); pGroup->AddLayer(pQuads); pQuads->m_lQuads.set_size(pQuadsItem->m_NumQuads); mem_copy(pQuads->m_lQuads.base_ptr(), pData, sizeof(CQuad)*pQuadsItem->m_NumQuads); DataFile.UnloadData(pQuadsItem->m_Data); } if(pLayer) pLayer->m_Flags = pLayerItem->m_Flags; } } } if(!m_pGameGroup) { MakeGameGroup(NewGroup()); } if(!m_pPhysicsLayer) { MakePhysicsLayer(new CLayerPhysics(50, 50)); m_pGameGroup->AddLayer(m_pPhysicsLayer); } if(!m_pEntityLayer) { MakeEntityLayer(new CLayerEntity(50, 50)); m_pGameGroup->AddLayer(m_pEntityLayer); } if(!m_pZoneLayer) { MakeZoneLayer(new CLayerZone(50, 50)); m_pGameGroup->AddLayer(m_pZoneLayer); } // load envelopes { CEnvPoint *pPoints = 0; { int Start, Num; DataFile.GetType(MAPITEMTYPE_ENVPOINTS, &Start, &Num); if(Num) pPoints = (CEnvPoint *)DataFile.GetItem(Start, 0, 0); } int Start, Num; DataFile.GetType(MAPITEMTYPE_ENVELOPE, &Start, &Num); for(int e = 0; e < Num; e++) { CMapItemEnvelope *pItem = (CMapItemEnvelope *)DataFile.GetItem(Start+e, 0, 0); CEnvelope *pEnv = new CEnvelope(pItem->m_Channels); pEnv->m_lPoints.set_size(pItem->m_NumPoints); mem_copy(pEnv->m_lPoints.base_ptr(), &pPoints[pItem->m_StartPoint], sizeof(CEnvPoint)*pItem->m_NumPoints); if(pItem->m_aName[0] != -1) // compatibility with old maps IntsToStr(pItem->m_aName, sizeof(pItem->m_aName)/sizeof(int), pEnv->m_aName); m_lEnvelopes.add(pEnv); if(pItem->m_Version >= 2) pEnv->m_Synchronized = pItem->m_Synchronized; } } } else return 0; return 1; }
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); }
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; }
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--; }
void CGameConsole::CInstance::OnInput(IInput::CEvent Event) { bool Handled = false; if(Event.m_Flags&IInput::FLAG_PRESS) { if(Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER) { if(m_Input.GetString()[0]) { if(m_Type == CONSOLETYPE_LOCAL || m_pGameConsole->Client()->RconAuthed()) { char *pEntry = m_History.Allocate(m_Input.GetLength()+1); mem_copy(pEntry, m_Input.GetString(), m_Input.GetLength()+1); } ExecuteLine(m_Input.GetString()); m_Input.Clear(); m_pHistoryEntry = 0x0; } Handled = true; } else if (Event.m_Key == KEY_UP) { if (m_pHistoryEntry) { char *pTest = m_History.Prev(m_pHistoryEntry); if (pTest) m_pHistoryEntry = pTest; } else m_pHistoryEntry = m_History.Last(); if (m_pHistoryEntry) m_Input.Set(m_pHistoryEntry); Handled = true; } else if (Event.m_Key == KEY_DOWN) { if (m_pHistoryEntry) m_pHistoryEntry = m_History.Next(m_pHistoryEntry); if (m_pHistoryEntry) m_Input.Set(m_pHistoryEntry); else m_Input.Clear(); Handled = true; } else if(Event.m_Key == KEY_TAB) { if(m_Type == CGameConsole::CONSOLETYPE_LOCAL || m_pGameConsole->Client()->RconAuthed()) { m_CompletionChosen++; m_CompletionEnumerationCount = 0; m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, m_Type != CGameConsole::CONSOLETYPE_LOCAL && m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands(), PossibleCommandsCompleteCallback, this); // handle wrapping if(m_CompletionEnumerationCount && m_CompletionChosen >= m_CompletionEnumerationCount) { m_CompletionChosen %= m_CompletionEnumerationCount; m_CompletionEnumerationCount = 0; m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, m_Type != CGameConsole::CONSOLETYPE_LOCAL && m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands(), PossibleCommandsCompleteCallback, this); } } } else if(Event.m_Key == KEY_PAGEUP) { ++m_BacklogActPage; } else if(Event.m_Key == KEY_PAGEDOWN) { --m_BacklogActPage; if(m_BacklogActPage < 0) m_BacklogActPage = 0; } } if(!Handled) m_Input.ProcessInput(Event); if(Event.m_Flags&IInput::FLAG_PRESS) { if(Event.m_Key != KEY_TAB) { m_CompletionChosen = -1; str_copy(m_aCompletionBuffer, m_Input.GetString(), sizeof(m_aCompletionBuffer)); } // find the current command { char aBuf[64] = {0}; const char *pSrc = GetString(); int i = 0; for(; i < (int)sizeof(aBuf)-1 && *pSrc && *pSrc != ' '; i++, pSrc++) aBuf[i] = *pSrc; aBuf[i] = 0; const IConsole::CCommandInfo *pCommand = m_pGameConsole->m_pConsole->GetCommandInfo(aBuf, m_CompletionFlagmask, m_Type != CGameConsole::CONSOLETYPE_LOCAL && m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands()); if(pCommand) { m_IsCommand = true; str_copy(m_aCommandName, pCommand->m_pName, IConsole::TEMPCMD_NAME_LENGTH); str_copy(m_aCommandHelp, pCommand->m_pHelp, IConsole::TEMPCMD_HELP_LENGTH); str_copy(m_aCommandParams, pCommand->m_pParams, IConsole::TEMPCMD_PARAMS_LENGTH); } else m_IsCommand = false; } } }
/*===========================================================================* * do_fork * *===========================================================================*/ PUBLIC int do_fork() { /* The process pointed to by 'mp' has forked. Create a child process. */ register struct mproc *rmp; /* pointer to parent */ register struct mproc *rmc; /* pointer to child */ int i, child_nr, t; char *sptr, *dptr; phys_clicks prog_clicks, child_base; #if (CHIP == INTEL) long prog_bytes; long parent_abs, child_abs; #endif /* If tables might fill up during FORK, don't even start since recovery half * way through is such a nuisance. */ rmp = mp; if (procs_in_use == NR_PROCS) return(EAGAIN); if (procs_in_use >= NR_PROCS - LAST_FEW && rmp->mp_effuid != 0)return(EAGAIN); /* Determine how much memory to allocate. */ prog_clicks = (phys_clicks) rmp->mp_seg[S].mem_len; prog_clicks += (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir); #if (CHIP == INTEL) if (rmp->mp_flags & SEPARATE) prog_clicks += rmp->mp_seg[T].mem_len; prog_bytes = (long) prog_clicks << CLICK_SHIFT; #endif if ( (child_base = alloc_mem(prog_clicks)) == NO_MEM) return(EAGAIN); #if (CHIP == INTEL) /* Create a copy of the parent's core image for the child. */ child_abs = (long) child_base << CLICK_SHIFT; parent_abs = (long) rmp->mp_seg[T].mem_phys << CLICK_SHIFT; i = mem_copy(ABS, 0, parent_abs, ABS, 0, child_abs, prog_bytes); if ( i < 0) panic("do_fork can't copy", i); #endif /* Find a slot in 'mproc' for the child process. A slot must exist. */ for (rmc = &mproc[0]; rmc < &mproc[NR_PROCS]; rmc++) if ( (rmc->mp_flags & IN_USE) == 0) break; /* Set up the child and its memory map; copy its 'mproc' slot from parent. */ child_nr = (int)(rmc - mproc); /* slot number of the child */ procs_in_use++; sptr = (char *) rmp; /* pointer to parent's 'mproc' slot */ dptr = (char *) rmc; /* pointer to child's 'mproc' slot */ i = sizeof(struct mproc); /* number of bytes in a proc slot. */ while (i--) *dptr++ = *sptr++;/* copy from parent slot to child's */ rmc->mp_parent = who; /* record child's parent */ rmc->mp_flags &= ~TRACED; /* child does not inherit trace status */ #if (CHIP == INTEL) rmc->mp_seg[T].mem_phys = child_base; rmc->mp_seg[D].mem_phys = child_base + rmc->mp_seg[T].mem_len; rmc->mp_seg[S].mem_phys = rmc->mp_seg[D].mem_phys + (rmp->mp_seg[S].mem_phys - rmp->mp_seg[D].mem_phys); #endif rmc->mp_exitstatus = 0; rmc->mp_sigstatus = 0; /* Find a free pid for the child and put it in the table. */ do { t = 0; /* 't' = 0 means pid still free */ next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1); for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) { t = 1; break; } rmc->mp_pid = next_pid; /* assign pid to child */ } while (t); /* Set process group. */ if (who == INIT_PROC_NR) rmc->mp_procgrp = rmc->mp_pid; /* Tell kernel and file system about the (now successful) FORK. */ #if (CHIP == M68000) sys_fork(who, child_nr, rmc->mp_pid, child_base); #else sys_fork(who, child_nr, rmc->mp_pid); #endif tell_fs(FORK, who, child_nr, rmc->mp_pid); #if (CHIP == INTEL) /* Report child's memory map to kernel. */ sys_newmap(child_nr, rmc->mp_seg); #endif /* Reply to child to wake it up. */ reply(child_nr, 0, 0, NIL_PTR); return(next_pid); /* child's pid */ }
static void run_service(struct omap_sdma_thc_service_binding_t *sv) { omap_sdma_service_msg_t msg; bool loop = true; // this is the bitmap of messages we are interested in receiving struct omap_sdma_service_selector selector = { .mem_copy = 1, .mem_copy_2d = 1, .mem_fill = 1, .mem_fill_2d = 1, }; while (loop) { // receive any message sv->recv_any(sv, &msg, selector); errval_t reterr = SYS_ERR_OK; // dispatch it switch(msg.msg) { case omap_sdma_mem_copy: reterr = mem_copy( msg.args.mem_copy.in.dst, msg.args.mem_copy.in.src); sv->send.mem_copy(sv, reterr); break; case omap_sdma_mem_fill: reterr = mem_fill( msg.args.mem_fill.in.dst, msg.args.mem_fill.in.color); sv->send.mem_fill(sv, reterr); break; case omap_sdma_mem_copy_2d: reterr = mem_copy_2d( msg.args.mem_copy_2d.in.dst, msg.args.mem_copy_2d.in.src, msg.args.mem_copy_2d.in.count, msg.args.mem_copy_2d.in.transparent, msg.args.mem_copy_2d.in.color); sv->send.mem_copy_2d(sv, reterr); break; case omap_sdma_mem_fill_2d: reterr = mem_fill_2d( msg.args.mem_fill_2d.in.dst, msg.args.mem_fill_2d.in.count, msg.args.mem_fill_2d.in.color); sv->send.mem_fill_2d(sv, reterr); break; default: debug_printf("unexpected message: %d\n", msg.msg); loop = false; break; } } free(sv); } void start_service(void) { errval_t err; struct omap_sdma_thc_export_info e_info; struct omap_sdma_thc_service_binding_t *sv; struct omap_sdma_binding *b; iref_t iref; err = omap_sdma_thc_export(&e_info, "sdma", get_default_waitset(), IDC_EXPORT_FLAGS_DEFAULT, &iref); if (err_is_fail(err)) { USER_PANIC_ERR(err, "thc export failed"); } DO_FINISH({ while(true) { err = omap_sdma_thc_accept(&e_info, &b); if (err_is_fail(err)) { USER_PANIC_ERR(err, "thc accept failed"); } sv = malloc(sizeof(struct omap_sdma_thc_service_binding_t)); assert(sv != NULL); err = omap_sdma_thc_init_service(sv, b, b); if (err_is_fail(err)) { USER_PANIC_ERR(err, "thc init failed"); } ASYNC({run_service(sv);}); } });
void CServerBrowser::Refresh(int Type) { // clear out everything m_ServerlistHeap.Reset(); m_NumServers = 0; m_NumSortedServers = 0; mem_zero(m_aServerlistIp, sizeof(m_aServerlistIp)); m_pFirstReqServer = 0; m_pLastReqServer = 0; m_NumRequests = 0; m_CurrentMaxRequests = g_Config.m_BrMaxRequests; // next token m_CurrentToken = (m_CurrentToken+1)&0xff; // m_ServerlistType = Type; if(Type == IServerBrowser::TYPE_LAN) { unsigned char Buffer[sizeof(SERVERBROWSE_GETINFO)+1]; CNetChunk Packet; int i; mem_copy(Buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)); Buffer[sizeof(SERVERBROWSE_GETINFO)] = m_CurrentToken; /* do the broadcast version */ Packet.m_ClientID = -1; mem_zero(&Packet, sizeof(Packet)); Packet.m_Address.type = m_pNetClient->NetType()|NETTYPE_LINK_BROADCAST; Packet.m_Flags = NETSENDFLAG_CONNLESS; Packet.m_DataSize = sizeof(Buffer); Packet.m_pData = Buffer; m_BroadcastTime = time_get(); for(i = 8303; i <= 8310; i++) { Packet.m_Address.port = i; m_pNetClient->Send(&Packet); } if(g_Config.m_Debug) m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "broadcasting for servers"); } else if(Type == IServerBrowser::TYPE_INTERNET) m_NeedRefresh = 1; else if(Type == IServerBrowser::TYPE_FAVORITES) { for(int i = 0; i < m_NumFavoriteServers; i++) Set(m_aFavoriteServers[i], IServerBrowser::SET_FAV_ADD, -1, 0); } else if(Type == IServerBrowser::TYPE_DDNET) { LoadDDNet(); // remove unknown elements of exclude list DDNetCountryFilterClean(); DDNetTypeFilterClean(); for(int i = 0; i < m_NumDDNetCountries; i++) { CDDNetCountry *pCntr = &m_aDDNetCountries[i]; // check for filter if(DDNetFiltered(g_Config.m_BrFilterExcludeCountries, pCntr->m_aName)) continue; for(int g = 0; g < pCntr->m_NumServers; g++) { if(!DDNetFiltered(g_Config.m_BrFilterExcludeTypes, pCntr->m_aTypes[g])) Set(pCntr->m_aServers[g], IServerBrowser::SET_DDNET_ADD, -1, 0); } } } }
int CInput::Update() { // keep the counter between 1..0xFFFF, 0 means not pressed m_InputCounter = (m_InputCounter%0xFFFF)+1; { int i; const Uint8 *pState = SDL_GetKeyboardState(&i); if(i >= KEY_LAST) i = KEY_LAST-1; mem_copy(m_aInputState, pState, i); } // these states must always be updated manually because they are not in the GetKeyState from SDL int i = SDL_GetMouseState(NULL, NULL); if(i&SDL_BUTTON(1)) m_aInputState[KEY_MOUSE_1] = 1; // 1 is left if(i&SDL_BUTTON(3)) m_aInputState[KEY_MOUSE_2] = 1; // 3 is right if(i&SDL_BUTTON(2)) m_aInputState[KEY_MOUSE_3] = 1; // 2 is middle if(i&SDL_BUTTON(4)) m_aInputState[KEY_MOUSE_4] = 1; if(i&SDL_BUTTON(5)) m_aInputState[KEY_MOUSE_5] = 1; if(i&SDL_BUTTON(6)) m_aInputState[KEY_MOUSE_6] = 1; if(i&SDL_BUTTON(7)) m_aInputState[KEY_MOUSE_7] = 1; if(i&SDL_BUTTON(8)) m_aInputState[KEY_MOUSE_8] = 1; if(i&SDL_BUTTON(9)) m_aInputState[KEY_MOUSE_9] = 1; { SDL_Event Event; while(SDL_PollEvent(&Event)) { int Key = -1; int Scancode = 0; int Action = IInput::FLAG_PRESS; switch (Event.type) { case SDL_TEXTINPUT: AddEvent(Event.text.text, 0, IInput::FLAG_TEXT); break; // handle keys case SDL_KEYDOWN: Key = KeycodeToKey(Event.key.keysym.sym); Scancode = Event.key.keysym.scancode; break; case SDL_KEYUP: Action = IInput::FLAG_RELEASE; Key = KeycodeToKey(Event.key.keysym.sym); Scancode = Event.key.keysym.scancode; break; // handle the joystick events case SDL_JOYBUTTONUP: Action = IInput::FLAG_RELEASE; // fall through case SDL_JOYBUTTONDOWN: Key = Event.jbutton.button + KEY_JOYSTICK_BUTTON_0; Scancode = Key; break; case SDL_JOYHATMOTION: switch (Event.jhat.value) { case SDL_HAT_LEFTUP: Key = KEY_JOY_HAT_LEFTUP; Scancode = Key; m_PreviousHat = Key; break; case SDL_HAT_UP: Key = KEY_JOY_HAT_UP; Scancode = Key; m_PreviousHat = Key; break; case SDL_HAT_RIGHTUP: Key = KEY_JOY_HAT_RIGHTUP; Scancode = Key; m_PreviousHat = Key; break; case SDL_HAT_LEFT: Key = KEY_JOY_HAT_LEFT; Scancode = Key; m_PreviousHat = Key; break; case SDL_HAT_CENTERED: Action = IInput::FLAG_RELEASE; Key = m_PreviousHat; Scancode = m_PreviousHat; m_PreviousHat = 0; break; case SDL_HAT_RIGHT: Key = KEY_JOY_HAT_RIGHT; Scancode = Key; m_PreviousHat = Key; break; case SDL_HAT_LEFTDOWN: Key = KEY_JOY_HAT_LEFTDOWN; Scancode = Key; m_PreviousHat = Key; break; case SDL_HAT_DOWN: Key = KEY_JOY_HAT_DOWN; Scancode = Key; m_PreviousHat = Key; break; case SDL_HAT_RIGHTDOWN: Key = KEY_JOY_HAT_RIGHTDOWN; Scancode = Key; m_PreviousHat = Key; break; } break; // handle mouse buttons case SDL_MOUSEBUTTONUP: Action = IInput::FLAG_RELEASE; // fall through case SDL_MOUSEBUTTONDOWN: if(Event.button.button == SDL_BUTTON_LEFT) Key = KEY_MOUSE_1; // ignore_convention if(Event.button.button == SDL_BUTTON_RIGHT) Key = KEY_MOUSE_2; // ignore_convention if(Event.button.button == SDL_BUTTON_MIDDLE) Key = KEY_MOUSE_3; // ignore_convention if(Event.button.button == 4) Key = KEY_MOUSE_4; // ignore_convention if(Event.button.button == 5) Key = KEY_MOUSE_5; // ignore_convention if(Event.button.button == 6) Key = KEY_MOUSE_6; // ignore_convention if(Event.button.button == 7) Key = KEY_MOUSE_7; // ignore_convention if(Event.button.button == 8) Key = KEY_MOUSE_8; // ignore_convention if(Event.button.button == 9) Key = KEY_MOUSE_9; // ignore_convention if(Event.button.button == SDL_BUTTON_LEFT) { if(Event.button.clicks%2 == 0) m_MouseDoubleClick = true; if(Event.button.clicks == 1) m_MouseDoubleClick = false; } Scancode = Key; break; case SDL_MOUSEWHEEL: if(Event.wheel.y > 0) Key = KEY_MOUSE_WHEEL_UP; // ignore_convention if(Event.wheel.y < 0) Key = KEY_MOUSE_WHEEL_DOWN; // ignore_convention Action |= IInput::FLAG_RELEASE; break; #if defined(CONF_PLATFORM_MACOSX) // Todo SDL: remove this when fixed (mouse state is faulty on start) case SDL_WINDOWEVENT: if(Event.window.event == SDL_WINDOWEVENT_MAXIMIZED) { MouseModeAbsolute(); MouseModeRelative(); } break; #endif // other messages case SDL_QUIT: return 1; } // if(Key != -1) { if(Action&IInput::FLAG_PRESS) { m_aInputState[Scancode] = 1; m_aInputCount[Key] = m_InputCounter; } AddEvent(0, Key, Action); } } } return 0; }
int CConsoleNetConnection::Recv(char *pLine, int MaxLength) { if(State() == NET_CONNSTATE_ONLINE) { if(m_BufferOffset) { // find message start int StartOffset = 0; while(m_aBuffer[StartOffset] == '\r' || m_aBuffer[StartOffset] == '\n') { // detect clients line ending format if(!m_LineEndingDetected) { m_aLineEnding[0] = m_aBuffer[StartOffset]; if(StartOffset+1 < m_BufferOffset && (m_aBuffer[StartOffset+1] == '\r' || m_aBuffer[StartOffset+1] == '\n') && m_aBuffer[StartOffset] != m_aBuffer[StartOffset+1]) m_aLineEnding[1] = m_aBuffer[StartOffset+1]; m_LineEndingDetected = true; } if(++StartOffset >= m_BufferOffset) { m_BufferOffset = 0; return 0; } } // find message end int EndOffset = StartOffset; while(m_aBuffer[EndOffset] != '\r' && m_aBuffer[EndOffset] != '\n') { if(++EndOffset >= m_BufferOffset) { if(StartOffset > 0) { mem_move(m_aBuffer, m_aBuffer+StartOffset, m_BufferOffset-StartOffset); m_BufferOffset -= StartOffset; } return 0; } } // extract message and update buffer if(MaxLength-1 < EndOffset-StartOffset) { if(StartOffset > 0) { mem_move(m_aBuffer, m_aBuffer+StartOffset, m_BufferOffset-StartOffset); m_BufferOffset -= StartOffset; } return 0; } mem_copy(pLine, m_aBuffer+StartOffset, EndOffset-StartOffset); pLine[EndOffset-StartOffset] = 0; str_sanitize_cc(pLine); mem_move(m_aBuffer, m_aBuffer+EndOffset, m_BufferOffset-EndOffset); m_BufferOffset -= EndOffset; return 1; } } return 0; }
void CServer::ProcessClientPacket(CNetChunk *pPacket) { int ClientID = pPacket->m_ClientID; CUnpacker Unpacker; Unpacker.Reset(pPacket->m_pData, pPacket->m_DataSize); // unpack msgid and system flag int Msg = Unpacker.GetInt(); int Sys = Msg&1; Msg >>= 1; if(Unpacker.Error()) return; if(Sys) { // system message if(Msg == NETMSG_INFO) { if(m_aClients[ClientID].m_State == CClient::STATE_AUTH) { const char *pVersion = Unpacker.GetString(CUnpacker::SANITIZE_CC); if(str_comp(pVersion, GameServer()->NetVersion()) != 0) { // wrong version char aReason[256]; str_format(aReason, sizeof(aReason), "Wrong version. Server is running '%s' and client '%s'", GameServer()->NetVersion(), pVersion); m_NetServer.Drop(ClientID, aReason); return; } const char *pPassword = Unpacker.GetString(CUnpacker::SANITIZE_CC); if(g_Config.m_Password[0] != 0 && str_comp(g_Config.m_Password, pPassword) != 0) { // wrong password m_NetServer.Drop(ClientID, "Wrong password"); return; } m_aClients[ClientID].m_State = CClient::STATE_CONNECTING; SendMap(ClientID); } } else if(Msg == NETMSG_REQUEST_MAP_DATA) { if(m_aClients[ClientID].m_State < CClient::STATE_CONNECTING) return; int Chunk = Unpacker.GetInt(); unsigned int ChunkSize = 1024-128; unsigned int Offset = Chunk * ChunkSize; int Last = 0; // drop faulty map data requests if(Chunk < 0 || Offset > m_CurrentMapSize) return; if(Offset+ChunkSize >= m_CurrentMapSize) { ChunkSize = m_CurrentMapSize-Offset; if(ChunkSize < 0) ChunkSize = 0; Last = 1; } CMsgPacker Msg(NETMSG_MAP_DATA); Msg.AddInt(Last); Msg.AddInt(m_CurrentMapCrc); Msg.AddInt(Chunk); Msg.AddInt(ChunkSize); Msg.AddRaw(&m_pCurrentMapData[Offset], ChunkSize); SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true); if(g_Config.m_Debug) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "sending chunk %d with size %d", Chunk, ChunkSize); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf); } } else if(Msg == NETMSG_READY) { if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTING) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%x addr=%s", ClientID, aAddrStr); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); m_aClients[ClientID].m_State = CClient::STATE_READY; GameServer()->OnClientConnected(ClientID); SendConnectionReady(ClientID); } } else if(Msg == NETMSG_ENTERGAME) { if(m_aClients[ClientID].m_State == CClient::STATE_READY && GameServer()->IsClientReady(ClientID)) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "player has entered the game. ClientID=%x addr=%s", ClientID, aAddrStr); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); m_aClients[ClientID].m_State = CClient::STATE_INGAME; GameServer()->OnClientEnter(ClientID); } } else if(Msg == NETMSG_INPUT) { CClient::CInput *pInput; int64 TagTime; m_aClients[ClientID].m_LastAckedSnapshot = Unpacker.GetInt(); int IntendedTick = Unpacker.GetInt(); int Size = Unpacker.GetInt(); // check for errors if(Unpacker.Error() || Size/4 > MAX_INPUT_SIZE) return; if(m_aClients[ClientID].m_LastAckedSnapshot > 0) m_aClients[ClientID].m_SnapRate = CClient::SNAPRATE_FULL; if(m_aClients[ClientID].m_Snapshots.Get(m_aClients[ClientID].m_LastAckedSnapshot, &TagTime, 0, 0) >= 0) m_aClients[ClientID].m_Latency = (int)(((time_get()-TagTime)*1000)/time_freq()); // add message to report the input timing // skip packets that are old if(IntendedTick > m_aClients[ClientID].m_LastInputTick) { int TimeLeft = ((TickStartTime(IntendedTick)-time_get())*1000) / time_freq(); CMsgPacker Msg(NETMSG_INPUTTIMING); Msg.AddInt(IntendedTick); Msg.AddInt(TimeLeft); SendMsgEx(&Msg, 0, ClientID, true); } m_aClients[ClientID].m_LastInputTick = IntendedTick; pInput = &m_aClients[ClientID].m_aInputs[m_aClients[ClientID].m_CurrentInput]; if(IntendedTick <= Tick()) IntendedTick = Tick()+1; pInput->m_GameTick = IntendedTick; for(int i = 0; i < Size/4; i++) pInput->m_aData[i] = Unpacker.GetInt(); mem_copy(m_aClients[ClientID].m_LatestInput.m_aData, pInput->m_aData, MAX_INPUT_SIZE*sizeof(int)); m_aClients[ClientID].m_CurrentInput++; m_aClients[ClientID].m_CurrentInput %= 200; // call the mod with the fresh input data if(m_aClients[ClientID].m_State == CClient::STATE_INGAME) GameServer()->OnClientDirectInput(ClientID, m_aClients[ClientID].m_LatestInput.m_aData); } else if(Msg == NETMSG_RCON_CMD) { const char *pCmd = Unpacker.GetString(); if(Unpacker.Error() == 0 && m_aClients[ClientID].m_Authed) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "ClientID=%d rcon='%s'", ClientID, pCmd); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); m_RconClientID = ClientID; m_RconAuthLevel = m_aClients[ClientID].m_Authed; Console()->SetAccessLevel(m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : IConsole::ACCESS_LEVEL_MOD); Console()->ExecuteLineFlag(pCmd, CFGFLAG_SERVER); Console()->SetAccessLevel(IConsole::ACCESS_LEVEL_ADMIN); m_RconClientID = IServer::RCON_CID_SERV; m_RconAuthLevel = AUTHED_ADMIN; } } else if(Msg == NETMSG_RCON_AUTH) { const char *pPw; Unpacker.GetString(); // login name, not used pPw = Unpacker.GetString(CUnpacker::SANITIZE_CC); if(Unpacker.Error() == 0) { if(g_Config.m_SvRconPassword[0] == 0 && g_Config.m_SvRconModPassword[0] == 0) { SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password and/or sv_rcon_mod_password to enable the remote console."); } else if(g_Config.m_SvRconPassword[0] && str_comp(pPw, g_Config.m_SvRconPassword) == 0) { CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); Msg.AddInt(1); //authed Msg.AddInt(1); //cmdlist SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); m_aClients[ClientID].m_Authed = AUTHED_ADMIN; int SendRconCmds = Unpacker.GetInt(); if(Unpacker.Error() == 0 && SendRconCmds) m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_ADMIN, CFGFLAG_SERVER); SendRconLine(ClientID, "Admin authentication successful. Full remote console access granted."); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (admin)", ClientID); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); } else if(g_Config.m_SvRconModPassword[0] && str_comp(pPw, g_Config.m_SvRconModPassword) == 0) { CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); Msg.AddInt(1); //authed Msg.AddInt(1); //cmdlist SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); m_aClients[ClientID].m_Authed = AUTHED_MOD; int SendRconCmds = Unpacker.GetInt(); if(Unpacker.Error() == 0 && SendRconCmds) m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_MOD, CFGFLAG_SERVER); SendRconLine(ClientID, "Moderator authentication successful. Limited remote console access granted."); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (moderator)", ClientID); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); } else if(g_Config.m_SvRconMaxTries) { m_aClients[ClientID].m_AuthTries++; char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Wrong password %d/%d.", m_aClients[ClientID].m_AuthTries, g_Config.m_SvRconMaxTries); SendRconLine(ClientID, aBuf); if(m_aClients[ClientID].m_AuthTries >= g_Config.m_SvRconMaxTries) { if(!g_Config.m_SvRconBantime) m_NetServer.Drop(ClientID, "Too many remote console authentication tries"); else m_ServerBan.BanAddr(m_NetServer.ClientAddr(ClientID), g_Config.m_SvRconBantime*60, "Too many remote console authentication tries"); } } else { SendRconLine(ClientID, "Wrong password."); } } } else if(Msg == NETMSG_PING) { CMsgPacker Msg(NETMSG_PING_REPLY); SendMsgEx(&Msg, 0, ClientID, true); } else { if(g_Config.m_Debug) { char aHex[] = "0123456789ABCDEF"; char aBuf[512]; for(int b = 0; b < pPacket->m_DataSize && b < 32; b++) { aBuf[b*3] = aHex[((const unsigned char *)pPacket->m_pData)[b]>>4]; aBuf[b*3+1] = aHex[((const unsigned char *)pPacket->m_pData)[b]&0xf]; aBuf[b*3+2] = ' '; aBuf[b*3+3] = 0; } char aBufMsg[256]; str_format(aBufMsg, sizeof(aBufMsg), "strange message ClientID=%d msg=%d data_size=%d", ClientID, Msg, pPacket->m_DataSize); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBufMsg); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf); } } }
void CEventVariable::Set(const char *pStr) { m_Type = EVENT_TYPE_STRING; Allocate(str_length(pStr) + 1); mem_copy(m_pData, pStr, str_length(pStr) + 1); }
void CNamePlates::RenderNameplate( const CNetObj_Character *pPrevChar, const CNetObj_Character *pPlayerChar, const CNetObj_PlayerInfo *pPlayerInfo ) { float IntraTick = Client()->IntraGameTick(); int ClientID = pPlayerInfo->m_ClientID; vec2 Position; if((!m_pClient->AntiPingPlayers() && !pPlayerInfo->m_Local) || m_pClient->m_Snap.m_SpecInfo.m_Active) { Position = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), IntraTick); } else if(!m_pClient->AntiPingPlayers() && pPlayerInfo->m_Local) { Position = vec2(m_pClient->m_LocalCharacterPos.x, m_pClient->m_LocalCharacterPos.y); } else { Position = m_pPlayers->m_CurPredictedPos[ClientID]; } bool OtherTeam; if(m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_Team == TEAM_SPECTATORS && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW) OtherTeam = false; else if(m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW) OtherTeam = m_pClient->m_Teams.Team(pPlayerInfo->m_ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID); else OtherTeam = m_pClient->m_Teams.Team(pPlayerInfo->m_ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_LocalClientID); float FontSize = 18.0f + 20.0f * g_Config.m_ClNameplatesSize / 100.0f; float FontSizeClan = 18.0f + 20.0f * g_Config.m_ClNameplatesClanSize / 100.0f; // render name plate if(!pPlayerInfo->m_Local || g_Config.m_ClNameplatesOwn) { float a = 1; if(g_Config.m_ClNameplatesAlways == 0) a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy], Position)/200.0f,16.0f), 0.0f, 1.0f); const char *pName = m_pClient->m_aClients[pPlayerInfo->m_ClientID].m_aName; if(str_comp(pName, m_aNamePlates[ClientID].m_aName) != 0 || FontSize != m_aNamePlates[ClientID].m_NameTextFontSize) { mem_copy(m_aNamePlates[ClientID].m_aName, pName, sizeof(m_aNamePlates[ClientID].m_aName)); m_aNamePlates[ClientID].m_NameTextFontSize = FontSize; m_aNamePlates[ClientID].m_NameTextWidth = TextRender()->TextWidth(0, FontSize, pName, -1); if(m_aNamePlates[ClientID].m_NameTextContainerIndex != -1) TextRender()->DeleteTextContainer(m_aNamePlates[ClientID].m_NameTextContainerIndex); CTextCursor Cursor; TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_RENDER); Cursor.m_LineWidth = -1; // create nameplates at standard zoom float ScreenX0, ScreenY0, ScreenX1, ScreenY1; Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); MapscreenToGroup(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y, Layers()->GameGroup()); m_aNamePlates[ClientID].m_NameTextContainerIndex = TextRender()->CreateTextContainer(&Cursor, pName); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } if(g_Config.m_ClNameplatesClan) { const char *pClan = m_pClient->m_aClients[ClientID].m_aClan; if(str_comp(pClan, m_aNamePlates[ClientID].m_aClanName) != 0 || FontSizeClan != m_aNamePlates[ClientID].m_ClanNameTextFontSize) { mem_copy(m_aNamePlates[ClientID].m_aClanName, pClan, sizeof(m_aNamePlates[ClientID].m_aClanName)); m_aNamePlates[ClientID].m_ClanNameTextFontSize = FontSizeClan; m_aNamePlates[ClientID].m_ClanNameTextWidth = TextRender()->TextWidth(0, FontSizeClan, pClan, -1); if(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex != -1) TextRender()->DeleteTextContainer(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex); CTextCursor Cursor; TextRender()->SetCursor(&Cursor, 0, 0, FontSizeClan, TEXTFLAG_RENDER); Cursor.m_LineWidth = -1; // create nameplates at standard zoom float ScreenX0, ScreenY0, ScreenX1, ScreenY1; Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); MapscreenToGroup(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y, Layers()->GameGroup()); m_aNamePlates[ClientID].m_ClanNameTextContainerIndex = TextRender()->CreateTextContainer(&Cursor, pClan); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } } float tw = m_aNamePlates[ClientID].m_NameTextWidth; vec3 rgb = vec3(1.0f, 1.0f, 1.0f); if(g_Config.m_ClNameplatesTeamcolors && m_pClient->m_Teams.Team(ClientID)) rgb = HslToRgb(vec3(m_pClient->m_Teams.Team(ClientID) / 64.0f, 1.0f, 0.75f)); STextRenderColor TColor; STextRenderColor TOutlineColor; if(OtherTeam) { TOutlineColor.Set(0.0f, 0.0f, 0.0f, 0.2f); TColor.Set(rgb.r, rgb.g, rgb.b, g_Config.m_ClShowOthersAlpha / 100.0f); } else { TOutlineColor.Set(0.0f, 0.0f, 0.0f, 0.5f*a); TColor.Set(rgb.r, rgb.g, rgb.b, a); } if(g_Config.m_ClNameplatesTeamcolors && m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) { if(m_pClient->m_aClients[ClientID].m_Team == TEAM_RED) TColor.Set(1.0f, 0.5f, 0.5f, a); else if(m_pClient->m_aClients[ClientID].m_Team == TEAM_BLUE) TColor.Set(0.7f, 0.7f, 1.0f, a); } if(m_aNamePlates[ClientID].m_NameTextContainerIndex != -1) TextRender()->RenderTextContainer(m_aNamePlates[ClientID].m_NameTextContainerIndex, &TColor, &TOutlineColor, Position.x - tw / 2.0f, Position.y - FontSize - 38.0f); if(g_Config.m_ClNameplatesClan) { if(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex != -1) TextRender()->RenderTextContainer(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex, &TColor, &TOutlineColor, Position.x - m_aNamePlates[ClientID].m_ClanNameTextWidth / 2.0f, Position.y - FontSize - FontSizeClan - 38.0f); } if(g_Config.m_Debug) // render client id when in debug as well { char aBuf[128]; str_format(aBuf, sizeof(aBuf),"%d", pPlayerInfo->m_ClientID); float Offset = g_Config.m_ClNameplatesClan ? (FontSize * 2 + FontSizeClan) : (FontSize * 2); float tw_id = TextRender()->TextWidth(0, FontSize, aBuf, -1); TextRender()->Text(0, Position.x-tw_id/2.0f, Position.y-Offset-38.0f, 28.0f, aBuf, -1); } TextRender()->TextColor(1,1,1,1); TextRender()->TextOutlineColor(0.0f, 0.0f, 0.0f, 0.3f); } }
void CEventVariable::Set(const char *pData, int Size) { m_Type = EVENT_TYPE_DATA; Allocate(Size); mem_copy(m_pData, pData, Size); }
int CControls::SnapInput(int *pData) { static int64 LastSendTime = 0; bool Send = false; // update player state if(m_pClient->m_pChat->IsActive()) m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_CHATTING; else if(m_pClient->m_pMenus->IsActive()) m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_IN_MENU; else m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_PLAYING; if(m_pClient->m_pScoreboard->Active()) m_InputData[g_Config.m_ClDummy].m_PlayerFlags |= PLAYERFLAG_SCOREBOARD; if(m_InputData[g_Config.m_ClDummy].m_PlayerFlags != PLAYERFLAG_PLAYING) m_JoystickTapTime = 0; // Do not launch hook on first tap if (m_pClient->m_pControls->m_ShowHookColl[g_Config.m_ClDummy]) m_InputData[g_Config.m_ClDummy].m_PlayerFlags |= PLAYERFLAG_AIM; if(m_LastData[g_Config.m_ClDummy].m_PlayerFlags != m_InputData[g_Config.m_ClDummy].m_PlayerFlags) Send = true; m_LastData[g_Config.m_ClDummy].m_PlayerFlags = m_InputData[g_Config.m_ClDummy].m_PlayerFlags; // we freeze the input if chat or menu is activated if(!(m_InputData[g_Config.m_ClDummy].m_PlayerFlags&PLAYERFLAG_PLAYING)) { ResetInput(g_Config.m_ClDummy); mem_copy(pData, &m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); // send once a second just to be sure if(time_get() > LastSendTime + time_freq()) Send = true; } else { m_InputData[g_Config.m_ClDummy].m_TargetX = (int)m_MousePos[g_Config.m_ClDummy].x; m_InputData[g_Config.m_ClDummy].m_TargetY = (int)m_MousePos[g_Config.m_ClDummy].y; if(!m_InputData[g_Config.m_ClDummy].m_TargetX && !m_InputData[g_Config.m_ClDummy].m_TargetY) { m_InputData[g_Config.m_ClDummy].m_TargetX = 1; m_MousePos[g_Config.m_ClDummy].x = 1; } // set direction m_InputData[g_Config.m_ClDummy].m_Direction = 0; if(m_InputDirectionLeft[g_Config.m_ClDummy] && !m_InputDirectionRight[g_Config.m_ClDummy]) m_InputData[g_Config.m_ClDummy].m_Direction = -1; if(!m_InputDirectionLeft[g_Config.m_ClDummy] && m_InputDirectionRight[g_Config.m_ClDummy]) m_InputData[g_Config.m_ClDummy].m_Direction = 1; // dummy copy moves if(g_Config.m_ClDummyCopyMoves) { CNetObj_PlayerInput *DummyInput = &Client()->DummyInput; DummyInput->m_Direction = m_InputData[g_Config.m_ClDummy].m_Direction; DummyInput->m_Hook = m_InputData[g_Config.m_ClDummy].m_Hook; DummyInput->m_Jump = m_InputData[g_Config.m_ClDummy].m_Jump; DummyInput->m_PlayerFlags = m_InputData[g_Config.m_ClDummy].m_PlayerFlags; DummyInput->m_TargetX = m_InputData[g_Config.m_ClDummy].m_TargetX; DummyInput->m_TargetY = m_InputData[g_Config.m_ClDummy].m_TargetY; DummyInput->m_WantedWeapon = m_InputData[g_Config.m_ClDummy].m_WantedWeapon; DummyInput->m_Fire += m_InputData[g_Config.m_ClDummy].m_Fire - m_LastData[g_Config.m_ClDummy].m_Fire; DummyInput->m_NextWeapon += m_InputData[g_Config.m_ClDummy].m_NextWeapon - m_LastData[g_Config.m_ClDummy].m_NextWeapon; DummyInput->m_PrevWeapon += m_InputData[g_Config.m_ClDummy].m_PrevWeapon - m_LastData[g_Config.m_ClDummy].m_PrevWeapon; m_InputData[!g_Config.m_ClDummy] = *DummyInput; } // stress testing if(g_Config.m_DbgStress) { float t = Client()->LocalTime(); mem_zero(&m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); m_InputData[g_Config.m_ClDummy].m_Direction = ((int)t/2)&1; m_InputData[g_Config.m_ClDummy].m_Jump = ((int)t); m_InputData[g_Config.m_ClDummy].m_Fire = ((int)(t*10)); m_InputData[g_Config.m_ClDummy].m_Hook = ((int)(t*2))&1; m_InputData[g_Config.m_ClDummy].m_WantedWeapon = ((int)t)%NUM_WEAPONS; m_InputData[g_Config.m_ClDummy].m_TargetX = (int)(sinf(t*3)*100.0f); m_InputData[g_Config.m_ClDummy].m_TargetY = (int)(cosf(t*3)*100.0f); } // check if we need to send input if(m_InputData[g_Config.m_ClDummy].m_Direction != m_LastData[g_Config.m_ClDummy].m_Direction) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_Jump != m_LastData[g_Config.m_ClDummy].m_Jump) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_Fire != m_LastData[g_Config.m_ClDummy].m_Fire) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_Hook != m_LastData[g_Config.m_ClDummy].m_Hook) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_WantedWeapon != m_LastData[g_Config.m_ClDummy].m_WantedWeapon) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_NextWeapon != m_LastData[g_Config.m_ClDummy].m_NextWeapon) Send = true; else if(m_InputData[g_Config.m_ClDummy].m_PrevWeapon != m_LastData[g_Config.m_ClDummy].m_PrevWeapon) Send = true; // send at at least 10hz if(time_get() > LastSendTime + time_freq()/25) Send = true; if(m_pClient->m_Snap.m_pLocalCharacter && m_pClient->m_Snap.m_pLocalCharacter->m_Weapon == WEAPON_NINJA && (m_InputData[g_Config.m_ClDummy].m_Direction || m_InputData[g_Config.m_ClDummy].m_Jump || m_InputData[g_Config.m_ClDummy].m_Hook)) Send = true; } // copy and return size m_LastData[g_Config.m_ClDummy] = m_InputData[g_Config.m_ClDummy]; if(!Send) return 0; LastSendTime = time_get(); mem_copy(pData, &m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0])); return sizeof(m_InputData[0]); }
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--; }
pvartype STDCALL load_var( pubyte* input, pubyte* output, uint count, puint size, uint align ) { pvartype psub; povmtype newtype; pubyte out = *output; pubyte ptr = *input; pvartype ret; uint i, off = 0, flag, len, k; ret = psub = ( pvartype )out; out += count * sizeof( vartype ); // print("Count=%i ---------\n", count ); for ( i = 0; i < count; i++ ) { mem_zero( psub, sizeof( vartype )); psub->type = load_convert( &ptr ); psub->off = align ? ( off >> 2 ) : off; flag = *ptr++; psub->flag = ( ubyte )flag; if ( flag & VAR_NAME ) { len = mem_copyuntilzero( out, ptr ); psub->name = out; ptr += len; // print(" Field %i %s\n", i, psub->name ); out += len; } newtype = ( povmtype )PCMD( psub->type ); off += flag & VAR_PARAM ? ( newtype->stsize << 2 ) : newtype->size; if ( flag & VAR_OFTYPE ) psub->oftype = load_convert( &ptr ); psub->ptr = ( puint )out; if ( flag & VAR_DIM ) { len = 1; psub->dim = *ptr++; for ( k = 0; k < psub->dim; k++ ) { *( puint )out = load_bwd( &ptr ); len *= *( puint )out; out += sizeof( uint ); } // Если reserved < 4 удаляем лишнее if ( psub->type == TReserved ) off += len - 4; } if ( flag & VAR_DATA ) { psub->data = 1; // print("Data=%s\n", psub->name ); if ( newtype->vmo.flag & GHTY_STACK ) len = newtype->size; else { if ( psub->type == TStr ) { len = mem_len( ptr ) + 1; // print("Val=%s\n", ptr ); } else { *( puint )out = load_bwd( &ptr ); len = *( puint )out; // print("Load %i %x\n", len, *( puint )ptr ); out += sizeof( uint ); } } mem_copy( out, ptr, len ); ptr += len; out += len; } // Alignment if ( align && ( off & 3 )) off += 4 - ( off & 0x3 ); // print("off = %i \n", off ); psub++; } *size = off; *output = out; *input = ptr; return ret; }
int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "saving to '%s'...", pFileName); m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "editor", aBuf); CDataFileWriter df; if(!df.Open(pStorage, pFileName)) { str_format(aBuf, sizeof(aBuf), "failed to open file '%s'...", pFileName); m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "editor", aBuf); return 0; } // save version { CMapItemVersion Item; Item.m_Version = 1; df.AddItem(MAPITEMTYPE_VERSION, 0, sizeof(Item), &Item); } // save map info { CMapItemInfo Item; Item.m_Version = 1; if(m_MapInfo.m_aAuthor[0]) Item.m_Author = df.AddData(str_length(m_MapInfo.m_aAuthor)+1, m_MapInfo.m_aAuthor); else Item.m_Author = -1; if(m_MapInfo.m_aVersion[0]) Item.m_MapVersion = df.AddData(str_length(m_MapInfo.m_aVersion)+1, m_MapInfo.m_aVersion); else Item.m_MapVersion = -1; if(m_MapInfo.m_aCredits[0]) Item.m_Credits = df.AddData(str_length(m_MapInfo.m_aCredits)+1, m_MapInfo.m_aCredits); else Item.m_Credits = -1; if(m_MapInfo.m_aLicense[0]) Item.m_License = df.AddData(str_length(m_MapInfo.m_aLicense)+1, m_MapInfo.m_aLicense); else Item.m_License = -1; df.AddItem(MAPITEMTYPE_INFO, 0, sizeof(Item), &Item); } // save images for(int i = 0; i < m_lImages.size(); i++) { CEditorImage *pImg = m_lImages[i]; // analyse the image for when saving (should be done when we load the image) // TODO! pImg->AnalyseTileFlags(); CMapItemImage Item; Item.m_Version = 1; Item.m_Width = pImg->m_Width; Item.m_Height = pImg->m_Height; Item.m_External = pImg->m_External; Item.m_ImageName = df.AddData(str_length(pImg->m_aName)+1, pImg->m_aName); if(pImg->m_External) Item.m_ImageData = -1; else Item.m_ImageData = df.AddData(Item.m_Width*Item.m_Height*4, pImg->m_pData); df.AddItem(MAPITEMTYPE_IMAGE, i, sizeof(Item), &Item); } // save layers int LayerCount = 0, GroupCount = 0; for(int g = 0; g < m_lGroups.size(); g++) { CLayerGroup *pGroup = m_lGroups[g]; if(!pGroup->m_SaveToMap) continue; CMapItemGroup GItem; GItem.m_Version = CMapItemGroup::CURRENT_VERSION; GItem.m_ParallaxX = pGroup->m_ParallaxX; GItem.m_ParallaxY = pGroup->m_ParallaxY; GItem.m_OffsetX = pGroup->m_OffsetX; GItem.m_OffsetY = pGroup->m_OffsetY; GItem.m_UseClipping = pGroup->m_UseClipping; GItem.m_ClipX = pGroup->m_ClipX; GItem.m_ClipY = pGroup->m_ClipY; GItem.m_ClipW = pGroup->m_ClipW; GItem.m_ClipH = pGroup->m_ClipH; GItem.m_StartLayer = LayerCount; GItem.m_NumLayers = 0; // save group name StrToInts(GItem.m_aName, sizeof(GItem.m_aName)/sizeof(int), pGroup->m_aName); for(int l = 0; l < pGroup->m_lLayers.size(); l++) { if(!pGroup->m_lLayers[l]->m_SaveToMap) continue; if(pGroup->m_lLayers[l]->m_Type == LAYERTYPE_TILES) { m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "editor", "saving tiles layer"); CLayerTiles *pLayer = (CLayerTiles *)pGroup->m_lLayers[l]; pLayer->PrepareForSave(); CMapItemLayerTilemap Item; Item.m_Version = 3; Item.m_Layer.m_Flags = pLayer->m_Flags; Item.m_Layer.m_Type = pLayer->m_Type; Item.m_Color = pLayer->m_Color; Item.m_ColorEnv = pLayer->m_ColorEnv; Item.m_ColorEnvOffset = pLayer->m_ColorEnvOffset; Item.m_Width = pLayer->m_Width; Item.m_Height = pLayer->m_Height; Item.m_Flags = pLayer->m_GameFlags; Item.m_Image = pLayer->m_Image; Item.m_Data = df.AddData(pLayer->m_Width*pLayer->m_Height*sizeof(CTile), pLayer->m_pTiles); // save layer name StrToInts(Item.m_aName, sizeof(Item.m_aName)/sizeof(int), pLayer->m_aName); df.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item); GItem.m_NumLayers++; LayerCount++; } else if(pGroup->m_lLayers[l]->m_Type == LAYERTYPE_QUADS) { m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "editor", "saving quads layer"); CLayerQuads *pLayer = (CLayerQuads *)pGroup->m_lLayers[l]; if(pLayer->m_lQuads.size()) { CMapItemLayerQuads Item; Item.m_Version = 2; Item.m_Layer.m_Flags = pLayer->m_Flags; Item.m_Layer.m_Type = pLayer->m_Type; Item.m_Image = pLayer->m_Image; // add the data Item.m_NumQuads = pLayer->m_lQuads.size(); Item.m_Data = df.AddDataSwapped(pLayer->m_lQuads.size()*sizeof(CQuad), pLayer->m_lQuads.base_ptr()); // save layer name StrToInts(Item.m_aName, sizeof(Item.m_aName)/sizeof(int), pLayer->m_aName); df.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item); // clean up //mem_free(quads); GItem.m_NumLayers++; LayerCount++; } } } df.AddItem(MAPITEMTYPE_GROUP, GroupCount++, sizeof(GItem), &GItem); } // save envelopes int PointCount = 0; for(int e = 0; e < m_lEnvelopes.size(); e++) { CMapItemEnvelope Item; Item.m_Version = CMapItemEnvelope::CURRENT_VERSION; Item.m_Channels = m_lEnvelopes[e]->m_Channels; Item.m_StartPoint = PointCount; Item.m_NumPoints = m_lEnvelopes[e]->m_lPoints.size(); Item.m_Synchronized = m_lEnvelopes[e]->m_Synchronized; StrToInts(Item.m_aName, sizeof(Item.m_aName)/sizeof(int), m_lEnvelopes[e]->m_aName); df.AddItem(MAPITEMTYPE_ENVELOPE, e, sizeof(Item), &Item); PointCount += Item.m_NumPoints; } // save points int TotalSize = sizeof(CEnvPoint) * PointCount; CEnvPoint *pPoints = (CEnvPoint *)mem_alloc(TotalSize, 1); PointCount = 0; for(int e = 0; e < m_lEnvelopes.size(); e++) { int Count = m_lEnvelopes[e]->m_lPoints.size(); mem_copy(&pPoints[PointCount], m_lEnvelopes[e]->m_lPoints.base_ptr(), sizeof(CEnvPoint)*Count); PointCount += Count; } df.AddItem(MAPITEMTYPE_ENVPOINTS, 0, TotalSize, pPoints); mem_free(pPoints); // finish the data file df.Finish(); m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "editor", "saving done"); return 1; }
void CEventVariable::Set(long int Value) { m_Type = EVENT_TYPE_INTEGER; Allocate(16); mem_copy(m_pData, &Value, sizeof(Value)); }
static void server_process_client_packet(NETCHUNK *packet) { int cid = packet->client_id; NETADDR addr; int sys; int msg = msg_unpack_start(packet->data, packet->data_size, &sys); if(clients[cid].state == SRVCLIENT_STATE_AUTH) { if(sys && msg == NETMSG_INFO) { char version[64]; const char *password; str_copy(version, msg_unpack_string(), 64); if(strcmp(version, mods_net_version()) != 0) { /* OH F**K! wrong version, drop him */ char reason[256]; str_format(reason, sizeof(reason), "wrong version. server is running '%s' and client '%s'.", mods_net_version(), version); netserver_drop(net, cid, reason); return; } str_copy(clients[cid].name, msg_unpack_string(), MAX_NAME_LENGTH); str_copy(clients[cid].clan, msg_unpack_string(), MAX_CLANNAME_LENGTH); password = msg_unpack_string(); if(config.password[0] != 0 && strcmp(config.password, password) != 0) { /* wrong password */ netserver_drop(net, cid, "wrong password"); return; } clients[cid].state = SRVCLIENT_STATE_CONNECTING; server_send_map(cid); } } else { if(sys) { /* system message */ if(msg == NETMSG_REQUEST_MAP_DATA) { int chunk = msg_unpack_int(); int chunk_size = 1024-128; int offset = chunk * chunk_size; int last = 0; /* drop faulty map data requests */ if(chunk < 0 || offset > current_map_size) return; if(offset+chunk_size >= current_map_size) { chunk_size = current_map_size-offset; if(chunk_size < 0) chunk_size = 0; last = 1; } msg_pack_start_system(NETMSG_MAP_DATA, MSGFLAG_VITAL|MSGFLAG_FLUSH); msg_pack_int(last); msg_pack_int(current_map_size); msg_pack_int(chunk_size); msg_pack_raw(¤t_map_data[offset], chunk_size); msg_pack_end(); server_send_msg(cid); if(config.debug) dbg_msg("server", "sending chunk %d with size %d", chunk, chunk_size); } else if(msg == NETMSG_READY) { if(clients[cid].state == SRVCLIENT_STATE_CONNECTING) { netserver_client_addr(net, cid, &addr); dbg_msg("server", "player is ready. cid=%x ip=%d.%d.%d.%d", cid, addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3] ); clients[cid].state = SRVCLIENT_STATE_READY; mods_connected(cid); } } else if(msg == NETMSG_ENTERGAME) { if(clients[cid].state == SRVCLIENT_STATE_READY) { netserver_client_addr(net, cid, &addr); dbg_msg("server", "player has entered the game. cid=%x ip=%d.%d.%d.%d", cid, addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3] ); clients[cid].state = SRVCLIENT_STATE_INGAME; mods_client_enter(cid); } } else if(msg == NETMSG_INPUT) { int tick, size, i; CLIENT_INPUT *input; int64 tagtime; clients[cid].last_acked_snapshot = msg_unpack_int(); tick = msg_unpack_int(); size = msg_unpack_int(); /* check for errors */ if(msg_unpack_error() || size/4 > MAX_INPUT_SIZE) return; if(clients[cid].last_acked_snapshot > 0) clients[cid].snap_rate = SRVCLIENT_SNAPRATE_FULL; if(snapstorage_get(&clients[cid].snapshots, clients[cid].last_acked_snapshot, &tagtime, 0, 0) >= 0) clients[cid].latency = (int)(((time_get()-tagtime)*1000)/time_freq()); /* add message to report the input timing */ /* skip packets that are old */ if(tick > clients[cid].last_input_tick) { int time_left = ((server_tick_start_time(tick)-time_get())*1000) / time_freq(); msg_pack_start_system(NETMSG_INPUTTIMING, 0); msg_pack_int(tick); msg_pack_int(time_left); msg_pack_end(); server_send_msg(cid); } clients[cid].last_input_tick = tick; input = &clients[cid].inputs[clients[cid].current_input]; if(tick <= server_tick()) tick = server_tick()+1; input->game_tick = tick; for(i = 0; i < size/4; i++) input->data[i] = msg_unpack_int(); mem_copy(clients[cid].latestinput.data, input->data, MAX_INPUT_SIZE*sizeof(int)); clients[cid].current_input++; clients[cid].current_input %= 200; /* call the mod with the fresh input data */ if(clients[cid].state == SRVCLIENT_STATE_INGAME) mods_client_direct_input(cid, clients[cid].latestinput.data); } else if(msg == NETMSG_RCON_CMD) { const char *cmd = msg_unpack_string(); if(msg_unpack_error() == 0 && clients[cid].authed) { dbg_msg("server", "cid=%d rcon='%s'", cid, cmd); console_execute_line(cmd); } } else if(msg == NETMSG_RCON_AUTH) { const char *pw; msg_unpack_string(); /* login name, not used */ pw = msg_unpack_string(); if(msg_unpack_error() == 0) { if(config.sv_rcon_password[0] == 0) { server_send_rcon_line(cid, "No rcon password set on server. Set sv_rcon_password to enable the remote console."); } else if(strcmp(pw, config.sv_rcon_password) == 0) { msg_pack_start_system(NETMSG_RCON_AUTH_STATUS, MSGFLAG_VITAL); msg_pack_int(1); msg_pack_end(); server_send_msg(cid); clients[cid].authed = 1; server_send_rcon_line(cid, "Authentication successful. Remote console access granted."); dbg_msg("server", "cid=%d authed", cid); } else { server_send_rcon_line(cid, "Wrong password."); } } } else if(msg == NETMSG_PING) { msg_pack_start_system(NETMSG_PING_REPLY, 0); msg_pack_end(); server_send_msg(cid); } else { char hex[] = "0123456789ABCDEF"; char buf[512]; int b; for(b = 0; b < packet->data_size && b < 32; b++) { buf[b*3] = hex[((const unsigned char *)packet->data)[b]>>4]; buf[b*3+1] = hex[((const unsigned char *)packet->data)[b]&0xf]; buf[b*3+2] = ' '; buf[b*3+3] = 0; } dbg_msg("server", "strange message cid=%d msg=%d data_size=%d", cid, msg, packet->data_size); dbg_msg("server", "%s", buf); } } else { /* game message */ if(clients[cid].state >= SRVCLIENT_STATE_READY) mods_message(msg, cid); } }
void CEventVariable::Set(float Value) { m_Type = EVENT_TYPE_FLOAT; Allocate(16); mem_copy(m_pData, &Value, sizeof(Value)); }
void CMenus::RenderSettingsPlayer(CUIRect MainView) { CUIRect Button; CUIRect LeftView, RightView; MainView.VSplitLeft(MainView.w/2, &LeftView, &RightView); LeftView.HSplitTop(20.0f, &Button, &LeftView); // render settings { char aBuf[128]; LeftView.HSplitTop(20.0f, &Button, &LeftView); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Name")); UI()->DoLabel(&Button, aBuf, 14.0, -1); Button.VSplitLeft(80.0f, 0, &Button); Button.VSplitLeft(180.0f, &Button, 0); static float Offset = 0.0f; if(DoEditBox(g_Config.m_PlayerName, &Button, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 14.0f, &Offset)) m_NeedSendinfo = true; // extra spacing LeftView.HSplitTop(10.0f, 0, &LeftView); static int s_DynamicCameraButton = 0; LeftView.HSplitTop(20.0f, &Button, &LeftView); if(DoButton_CheckBox(&s_DynamicCameraButton, Localize("Dynamic Camera"), g_Config.m_ClMouseDeadzone != 0, &Button)) { if(g_Config.m_ClMouseDeadzone) { g_Config.m_ClMouseFollowfactor = 0; g_Config.m_ClMouseMaxDistance = 400; g_Config.m_ClMouseDeadzone = 0; } else { g_Config.m_ClMouseFollowfactor = 60; g_Config.m_ClMouseMaxDistance = 1000; g_Config.m_ClMouseDeadzone = 300; } } LeftView.HSplitTop(20.0f, &Button, &LeftView); if(DoButton_CheckBox(&g_Config.m_ClAutoswitchWeapons, Localize("Switch weapon on pickup"), g_Config.m_ClAutoswitchWeapons, &Button)) g_Config.m_ClAutoswitchWeapons ^= 1; LeftView.HSplitTop(20.0f, &Button, &LeftView); if(DoButton_CheckBox(&g_Config.m_ClNameplates, Localize("Show name plates"), g_Config.m_ClNameplates, &Button)) g_Config.m_ClNameplates ^= 1; //if(config.cl_nameplates) { LeftView.HSplitTop(20.0f, &Button, &LeftView); Button.VSplitLeft(15.0f, 0, &Button); if(DoButton_CheckBox(&g_Config.m_ClNameplatesAlways, Localize("Always show name plates"), g_Config.m_ClNameplatesAlways, &Button)) g_Config.m_ClNameplatesAlways ^= 1; } { const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(max(0, m_pClient->m_pSkins->Find(g_Config.m_PlayerSkin))); CTeeRenderInfo OwnSkinInfo; OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture; OwnSkinInfo.m_ColorBody = vec4(1, 1, 1, 1); OwnSkinInfo.m_ColorFeet = vec4(1, 1, 1, 1); if(g_Config.m_PlayerUseCustomColor) { OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorBody); OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorFeet); OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture; } OwnSkinInfo.m_Size = UI()->Scale()*50.0f; LeftView.HSplitTop(20.0f, &Button, &LeftView); LeftView.HSplitTop(20.0f, &Button, &LeftView); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Your skin")); UI()->DoLabel(&Button, aBuf, 14.0, -1); CUIRect SkinRect; LeftView.VSplitLeft(LeftView.w/1.2f, &SkinRect, 0); SkinRect.HSplitTop(50.0f, &SkinRect, 0); RenderTools()->DrawUIRect(&SkinRect, vec4(1, 1, 1, 0.25f), CUI::CORNER_ALL, 10.0f); Button.VSplitLeft(30.0f, 0, &Button); Button.HSplitTop(50.0f, 0, &Button); RenderTools()->RenderTee(CAnimState::GetIdle(), &OwnSkinInfo, 0, vec2(1, 0), vec2(Button.x, Button.y)); LeftView.HSplitTop(20.0f, &Button, &LeftView); Button.HSplitTop(15.0f, 0, &Button); Button.VSplitLeft(100.0f, 0, &Button); str_format(aBuf, sizeof(aBuf), "%s", g_Config.m_PlayerSkin); CTextCursor Cursor; TextRender()->SetCursor(&Cursor, Button.x, Button.y, 14.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = SkinRect.w-(Button.x-SkinRect.x)-5.0f; TextRender()->TextEx(&Cursor, aBuf, -1); } RightView.HSplitTop(20.0f, &Button, &RightView); RightView.HSplitTop(20.0f, &Button, &RightView); if(DoButton_CheckBox(&g_Config.m_PlayerColorBody, Localize("Custom colors"), g_Config.m_PlayerUseCustomColor, &Button)) { g_Config.m_PlayerUseCustomColor = g_Config.m_PlayerUseCustomColor?0:1; m_NeedSendinfo = true; } if(g_Config.m_PlayerUseCustomColor) { int *paColors[2]; paColors[0] = &g_Config.m_PlayerColorBody; paColors[1] = &g_Config.m_PlayerColorFeet; const char *paParts[] = { Localize("Body"), Localize("Feet")}; const char *paLabels[] = { Localize("Hue"), Localize("Sat."), Localize("Lht.")}; static int s_aColorSlider[2][3] = {{0}}; //static float v[2][3] = {{0, 0.5f, 0.25f}, {0, 0.5f, 0.25f}}; for(int i = 0; i < 2; i++) { CUIRect Text; RightView.HSplitTop(20.0f, &Text, &RightView); Text.VSplitLeft(15.0f, 0, &Text); UI()->DoLabel(&Text, paParts[i], 14.0f, -1); int PrevColor = *paColors[i]; int Color = 0; for(int s = 0; s < 3; s++) { CUIRect Text; RightView.HSplitTop(19.0f, &Button, &RightView); Button.VSplitLeft(30.0f, 0, &Button); Button.VSplitLeft(70.0f, &Text, &Button); Button.VSplitRight(5.0f, &Button, 0); Button.HSplitTop(4.0f, 0, &Button); float k = ((PrevColor>>((2-s)*8))&0xff) / 255.0f; k = DoScrollbarH(&s_aColorSlider[i][s], &Button, k); Color <<= 8; Color += clamp((int)(k*255), 0, 255); UI()->DoLabel(&Text, paLabels[s], 15.0f, -1); } if(*paColors[i] != Color) m_NeedSendinfo = true; *paColors[i] = Color; RightView.HSplitTop(5.0f, 0, &RightView); } } MainView.HSplitTop(MainView.h/2, 0, &MainView); // render skinselector static bool s_InitSkinlist = true; static sorted_array<const CSkins::CSkin *> s_paSkinList; static float s_ScrollValue = 0; if(s_InitSkinlist) { s_paSkinList.clear(); for(int i = 0; i < m_pClient->m_pSkins->Num(); ++i) { const CSkins::CSkin *s = m_pClient->m_pSkins->Get(i); // no special skins if(s->m_aName[0] == 'x' && s->m_aName[1] == '_') continue; s_paSkinList.add(s); } s_InitSkinlist = false; } int OldSelected = -1; UiDoListboxStart(&s_InitSkinlist, &MainView, 50.0f, Localize("Skins"), "", s_paSkinList.size(), 4, OldSelected, s_ScrollValue); for(int i = 0; i < s_paSkinList.size(); ++i) { const CSkins::CSkin *s = s_paSkinList[i]; if(s == 0) continue; if(str_comp(s->m_aName, g_Config.m_PlayerSkin) == 0) OldSelected = i; CListboxItem Item = UiDoListboxNextItem(&s_paSkinList[i], OldSelected == i); if(Item.m_Visible) { CTeeRenderInfo Info; Info.m_Texture = s->m_OrgTexture; Info.m_ColorBody = vec4(1, 1, 1, 1); Info.m_ColorFeet = vec4(1, 1, 1, 1); if(g_Config.m_PlayerUseCustomColor) { Info.m_ColorBody = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorBody); Info.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorFeet); Info.m_Texture = s->m_ColorTexture; } Info.m_Size = UI()->Scale()*50.0f; Item.m_Rect.HSplitTop(5.0f, 0, &Item.m_Rect); // some margin from the top RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, 0, vec2(1, 0), vec2(Item.m_Rect.x+Item.m_Rect.w/2, Item.m_Rect.y+Item.m_Rect.h/2)); if(g_Config.m_Debug) { vec3 BloodColor = g_Config.m_PlayerUseCustomColor ? m_pClient->m_pSkins->GetColorV3(g_Config.m_PlayerColorBody) : s->m_BloodColor; Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(BloodColor.r, BloodColor.g, BloodColor.b, 1.0f); IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, 12, 12); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } } } const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); if(OldSelected != NewSelected) { mem_copy(g_Config.m_PlayerSkin, s_paSkinList[NewSelected]->m_aName, sizeof(g_Config.m_PlayerSkin)); m_NeedSendinfo = true; } }
void CEventVariable::Set(bool Value) { m_Type = EVENT_TYPE_BOOL; Allocate(16); mem_copy(m_pData, &Value, sizeof(Value)); }
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; }
void CEventVariable::Set(char Value) { m_Type = EVENT_TYPE_CHAR; Allocate(16); mem_copy(m_pData, &Value, sizeof(Value)); }
bool CChat::OnInput(IInput::CEvent Event) { if(m_Mode == MODE_NONE) return false; if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE) { m_Mode = MODE_NONE; m_pClient->OnRelease(); } else if(Event.m_Flags&IInput::FLAG_PRESS && (Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER)) { if(m_Input.GetString()[0]) { bool AddEntry = false; if(m_LastChatSend+time_freq() < time_get()) { Say(m_Mode == MODE_ALL ? 0 : 1, m_Input.GetString()); AddEntry = true; } else if(m_PendingChatCounter < 3) { ++m_PendingChatCounter; AddEntry = true; } if(AddEntry) { CHistoryEntry *pEntry = m_History.Allocate(sizeof(CHistoryEntry)+m_Input.GetLength()); pEntry->m_Team = m_Mode == MODE_ALL ? 0 : 1; mem_copy(pEntry->m_aText, m_Input.GetString(), m_Input.GetLength()+1); } } m_pHistoryEntry = 0x0; m_Mode = MODE_NONE; m_pClient->OnRelease(); } if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_TAB) { // fill the completion buffer if(m_CompletionChosen < 0) { const char *pCursor = m_Input.GetString()+m_Input.GetCursorOffset(); for(int Count = 0; Count < m_Input.GetCursorOffset() && *(pCursor-1) != ' '; --pCursor, ++Count); m_PlaceholderOffset = pCursor-m_Input.GetString(); for(m_PlaceholderLength = 0; *pCursor && *pCursor != ' '; ++pCursor) ++m_PlaceholderLength; str_copy(m_aCompletionBuffer, m_Input.GetString()+m_PlaceholderOffset, min(static_cast<int>(sizeof(m_aCompletionBuffer)), m_PlaceholderLength+1)); } // find next possible name const char *pCompletionString = 0; if(m_CompletionChosen < 0 && m_CompletionFav >= 0) m_CompletionChosen = m_CompletionFav; else { if (m_ReverseCompletion) m_CompletionChosen = (m_CompletionChosen - 1 + 2 * MAX_CLIENTS) % (2 * MAX_CLIENTS); else m_CompletionChosen = (m_CompletionChosen + 1) % (2 * MAX_CLIENTS); } for(int i = 0; i < 2*MAX_CLIENTS; ++i) { int SearchType; int Index; if(m_ReverseCompletion) { SearchType = ((m_CompletionChosen-i +2*MAX_CLIENTS)%(2*MAX_CLIENTS))/MAX_CLIENTS; Index = (m_CompletionChosen-i + MAX_CLIENTS )%MAX_CLIENTS; } else { SearchType = ((m_CompletionChosen+i)%(2*MAX_CLIENTS))/MAX_CLIENTS; Index = (m_CompletionChosen+i)%MAX_CLIENTS; } if(!m_pClient->m_aClients[Index].m_Active) continue; bool Found = false; if(SearchType == 1) { if(str_comp_nocase_num(m_pClient->m_aClients[Index].m_aName, m_aCompletionBuffer, str_length(m_aCompletionBuffer)) && str_find_nocase(m_pClient->m_aClients[Index].m_aName, m_aCompletionBuffer)) Found = true; } else if(!str_comp_nocase_num(m_pClient->m_aClients[Index].m_aName, m_aCompletionBuffer, str_length(m_aCompletionBuffer))) Found = true; if(Found) { pCompletionString = m_pClient->m_aClients[Index].m_aName; m_CompletionChosen = Index+SearchType*MAX_CLIENTS; m_CompletionFav = m_CompletionChosen; break; } } // insert the name if(pCompletionString) { char aBuf[256]; // add part before the name str_copy(aBuf, m_Input.GetString(), min(static_cast<int>(sizeof(aBuf)), m_PlaceholderOffset+1)); // add the name str_append(aBuf, pCompletionString, sizeof(aBuf)); // add seperator const char *pSeparator = ""; if(*(m_Input.GetString()+m_PlaceholderOffset+m_PlaceholderLength) != ' ') pSeparator = m_PlaceholderOffset == 0 ? ": " : " "; else if(m_PlaceholderOffset == 0) pSeparator = ":"; if(*pSeparator) str_append(aBuf, pSeparator, sizeof(aBuf)); // add part after the name str_append(aBuf, m_Input.GetString()+m_PlaceholderOffset+m_PlaceholderLength, sizeof(aBuf)); m_PlaceholderLength = str_length(pSeparator)+str_length(pCompletionString); m_OldChatStringLength = m_Input.GetLength(); m_Input.Set(aBuf); m_Input.SetCursorOffset(m_PlaceholderOffset+m_PlaceholderLength); m_InputUpdate = true; } } else { m_OldChatStringLength = m_Input.GetLength(); if(m_Input.ProcessInput(Event)) { m_InputUpdate = true; // reset name completion process m_CompletionChosen = -1; } } if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_LCTRL) m_ReverseCompletion = true; else if(Event.m_Flags&IInput::FLAG_RELEASE && Event.m_Key == KEY_LCTRL) m_ReverseCompletion = false; if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_UP) { if(m_pHistoryEntry) { CHistoryEntry *pTest = m_History.Prev(m_pHistoryEntry); if(pTest) m_pHistoryEntry = pTest; } else m_pHistoryEntry = m_History.Last(); if(m_pHistoryEntry) m_Input.Set(m_pHistoryEntry->m_aText); } else if (Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_DOWN) { if(m_pHistoryEntry) m_pHistoryEntry = m_History.Next(m_pHistoryEntry); if (m_pHistoryEntry) m_Input.Set(m_pHistoryEntry->m_aText); else m_Input.Clear(); } return true; }
/* TODO: chopp up this function into smaller working parts */ int CNetServer::Recv(CNetChunk *pChunk) { unsigned Now = time_timestamp(); while(1) { NETADDR Addr; // check for a chunk if(m_RecvUnpacker.FetchChunk(pChunk)) return 1; // TODO: empty the recvinfo int Bytes = net_udp_recv(m_Socket, &Addr, m_RecvUnpacker.m_aBuffer, NET_MAX_PACKETSIZE); // no more packets for now if(Bytes <= 0) break; if(CNetBase::UnpackPacket(m_RecvUnpacker.m_aBuffer, Bytes, &m_RecvUnpacker.m_Data) == 0) { CBan *pBan = 0; NETADDR BanAddr = Addr; int IpHash = (BanAddr.ip[0]+BanAddr.ip[1]+BanAddr.ip[2]+BanAddr.ip[3]+BanAddr.ip[4]+BanAddr.ip[5]+BanAddr.ip[6]+BanAddr.ip[7]+ BanAddr.ip[8]+BanAddr.ip[9]+BanAddr.ip[10]+BanAddr.ip[11]+BanAddr.ip[12]+BanAddr.ip[13]+BanAddr.ip[14]+BanAddr.ip[15])&0xff; int Found = 0; BanAddr.port = 0; // search a ban for(pBan = m_aBans[IpHash]; pBan; pBan = pBan->m_pHashNext) { if(net_addr_comp(&pBan->m_Info.m_Addr, &BanAddr) == 0) break; } // check if we just should drop the packet if(pBan) { // banned, reply with a message char BanStr[128]; if(pBan->m_Info.m_Expires && pBan->m_Info.m_Expires != -1) { int Mins = ((pBan->m_Info.m_Expires - Now)+59)/60; if(Mins == 1) str_format(BanStr, sizeof(BanStr), "Banned for 1 minute (%s)", pBan->m_Info.m_Reason); else str_format(BanStr, sizeof(BanStr), "Banned for %d minutes (%s)", Mins, pBan->m_Info.m_Reason); } else str_format(BanStr, sizeof(BanStr), "Banned for life (%s)", pBan->m_Info.m_Reason); CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, BanStr, str_length(BanStr)+1); continue; } if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONNLESS) { pChunk->m_Flags = NETSENDFLAG_CONNLESS; pChunk->m_ClientID = -1; pChunk->m_Address = Addr; pChunk->m_DataSize = m_RecvUnpacker.m_Data.m_DataSize; pChunk->m_pData = m_RecvUnpacker.m_Data.m_aChunkData; return 1; } else { // TODO: check size here if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && m_RecvUnpacker.m_Data.m_aChunkData[0] == NET_CTRLMSG_CONNECT) { Found = 0; // check if we already got this client for(int i = 0; i < MaxClients(); i++) { NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress(); if(m_aSlots[i].m_Connection.State() != NET_CONNSTATE_OFFLINE && net_addr_comp(&PeerAddr, &Addr) == 0) { Found = 1; // silent ignore.. we got this client already break; } } // client that wants to connect if(!Found) { CNetChunk Packet; char aBuffer[sizeof(BANMASTER_IPCHECK) + NETADDR_MAXSTRSIZE]; mem_copy(aBuffer, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)); net_addr_str(&Addr, aBuffer + sizeof(BANMASTER_IPCHECK), sizeof(aBuffer) - sizeof(BANMASTER_IPCHECK)); Packet.m_ClientID = -1; Packet.m_Flags = NETSENDFLAG_CONNLESS; Packet.m_DataSize = str_length(aBuffer) + 1; Packet.m_pData = aBuffer; for(int i = 0; i < m_NumBanmasters; i++) { Packet.m_Address = m_aBanmasters[i]; Send(&Packet); } // only allow a specific number of players with the same ip NETADDR ThisAddr = Addr, OtherAddr; int FoundAddr = 1; ThisAddr.port = 0; for(int i = 0; i < MaxClients(); ++i) { if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE) continue; OtherAddr = m_aSlots[i].m_Connection.PeerAddress(); OtherAddr.port = 0; if(!net_addr_comp(&ThisAddr, &OtherAddr)) { if(FoundAddr++ >= m_MaxClientsPerIP) { char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Only %d players with the same IP are allowed", m_MaxClientsPerIP); CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, aBuf, sizeof(aBuf)); return 0; } } } for(int i = 0; i < MaxClients(); i++) { if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE) { Found = 1; m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr); if(m_pfnNewClient) m_pfnNewClient(i, m_UserPtr); break; } } if(!Found) { const char FullMsg[] = "This server is full"; CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, FullMsg, sizeof(FullMsg)); } } } else { // normal packet, find matching slot for(int i = 0; i < MaxClients(); i++) { NETADDR PeerAddr = m_aSlots[i].m_Connection.PeerAddress(); if(net_addr_comp(&PeerAddr, &Addr) == 0) { if(m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr)) { if(m_RecvUnpacker.m_Data.m_DataSize) m_RecvUnpacker.Start(&Addr, &m_aSlots[i].m_Connection, i); } } } } } } } return 0; }