void CSector::MoveItemToSector( CItem * pItem, bool fActive ) { ADDTOCALLSTACK("CSector::MoveItemToSector"); // remove from previous list and put in new. // May just be setting a timer. SetTimer or MoveTo() ASSERT( pItem ); if (IsSleeping()) { if (CanSleep(true)) { pItem->GoSleep(); } else { GoAwake(); if (pItem->IsSleeping()) pItem->GoAwake(); } } else { if (pItem->IsSleeping()) pItem->GoAwake(); } if ( fActive ) m_Items_Timer.AddItemToSector( pItem ); else m_Items_Inert.AddItemToSector( pItem ); }
void CSector::SetSectorWakeStatus() { ADDTOCALLSTACK("CSector::SetSectorWakeStatus"); // Ships may enter a sector before it's riders ! ships need working timers to move ! m_Chars_Active.m_timeLastClient = g_World.GetCurrentTime().GetTimeRaw(); if (IsSleeping()) { GoAwake(); } }
bool CSector::MoveCharToSector( CChar * pChar ) { ADDTOCALLSTACK("CSector::MoveCharToSector"); // Move a CChar into this CSector. ASSERT(pChar); if ( IsCharActiveIn(pChar) ) return false; // already here // Check my save parity vs. this sector's if ( pChar->IsStatFlag( STATF_SAVEPARITY ) != m_fSaveParity ) { if ( g_World.IsSaving()) { if ( m_fSaveParity == g_World.m_fSaveParity ) { // Save out the CChar now. the sector has already been saved. if ( pChar->m_pPlayer ) pChar->r_WriteParity(g_World.m_FilePlayers); else pChar->r_WriteParity(g_World.m_FileWorld); } else { // We need to write out this CSector now. (before adding client) r_Write(); } } } m_Chars_Active.AddCharActive(pChar); // remove from previous spot. if (IsSleeping()) { CClient *pClient = pChar->GetClient(); if (pClient) // A client just entered { GoAwake(); // Awake the sector } else if (!pChar->IsSleeping()) // An NPC entered, but the sector is sleeping { pChar->GoSleep(); // then make the NPC sleep too. } } else { if (pChar->m_pNPC && pChar->IsSleeping()) { pChar->GoAwake(); } } return true; }
bool CSector::r_WriteVal( lpctstr pszKey, CSString & sVal, CTextConsole * pSrc ) { ADDTOCALLSTACK("CSector::r_WriteVal"); EXC_TRY("WriteVal"); static const CValStr sm_ComplexityTitles[] = { { "HIGH", INT32_MIN }, // speech can be very complex if low char count { "MEDIUM", 5 }, { "LOW", 10 }, { nullptr, INT32_MAX } }; SC_TYPE key = (SC_TYPE)FindTableHead(pszKey, sm_szLoadKeys, CountOf(sm_szLoadKeys) - 1); switch ( key ) { case SC_CANSLEEP: { pszKey += 8; bool fCheckAdjacents = Exp_GetVal(pszKey); sVal.FormatBVal(CanSleep(fCheckAdjacents)); return true; } case SC_CLIENTS: sVal.FormatSTVal(m_Chars_Active.GetClientsNumber()); return true; case SC_COLDCHANCE: sVal.FormatVal( GetColdChance()); return true; case SC_COMPLEXITY: if ( pszKey[10] == '.' ) { pszKey += 11; sVal = ( ! strcmpi( pszKey, sm_ComplexityTitles->FindName( (int)GetCharComplexity() )) ) ? "1" : "0"; return true; } sVal.FormatSTVal( GetCharComplexity() ); return true; case SC_FLAGS: sVal.FormatHex(m_dwFlags); return true; case SC_LIGHT: sVal.FormatVal(GetLight()); return true; case SC_LOCALTIME: sVal = GetLocalGameTime(); return true; case SC_LOCALTOD: sVal.FormatVal( GetLocalTime()); return true; case SC_NUMBER: sVal.FormatVal(m_index); return true; case SC_ISDARK: sVal.FormatVal( IsDark() ); return true; case SC_ISNIGHTTIME: { int iMinutes = GetLocalTime(); sVal = ( iMinutes < 7*60 || iMinutes > (9+12)*60 ) ? "1" : "0"; } return true; case SC_ISSLEEPING: sVal.FormatVal(IsSleeping()); return true; case SC_RAINCHANCE: sVal.FormatVal( GetRainChance()); return true; case SC_ITEMCOUNT: sVal.FormatSTVal(GetItemComplexity()); return true; case SC_SEASON: sVal.FormatVal((int)GetSeason()); return true; case SC_WEATHER: sVal.FormatVal((int)GetWeather()); return true; } EXC_CATCH; EXC_DEBUG_START; EXC_ADD_KEYRET(pSrc); EXC_DEBUG_END; return false; }
bool CSector::r_Verb( CScript & s, CTextConsole * pSrc ) { ADDTOCALLSTACK("CSector::r_Verb"); EXC_TRY("Verb"); ASSERT(pSrc); int index = FindTableSorted( s.GetKey(), sm_szVerbKeys, CountOf(sm_szVerbKeys)-1 ); switch (index) { case SEV_ALLCHARS: // "ALLCHARS" v_AllChars( s, pSrc ); break; case SEV_ALLCHARSIDLE: // "ALLCHARSIDLE" v_AllCharsIdle( s, pSrc ); break; case SEV_ALLCLIENTS: // "ALLCLIENTS" v_AllClients( s, pSrc ); break; case SEV_ALLITEMS: // "ALLITEMS" v_AllItems( s, pSrc ); break; case SEV_AWAKE: if (!IsSleeping()) { break; } GoAwake(); break; case SEV_DRY: // "DRY" SetWeather( WEATHER_DRY ); break; case SEV_LIGHT: if ( g_Cfg.m_bAllowLightOverride ) SetLight( (s.HasArgs()) ? s.GetArgVal() : -1 ); else g_Log.EventWarn("AllowLightOverride flag is disabled in sphere.ini, so sector's LIGHT property wasn't set\n"); break; case SEV_RAIN: SetWeather(s.HasArgs() ? static_cast<WEATHER_TYPE>(s.GetArgVal()) : WEATHER_RAIN); break; case SEV_RESPAWN: ( toupper( s.GetArgRaw()[0] ) == 'A' ) ? g_World.RespawnDeadNPCs() : RespawnDeadNPCs(); break; case SEV_RESTOCK: // x // set restock time of all vendors in World, set the respawn time of all spawns in World. ( toupper( s.GetArgRaw()[0] ) == 'A' ) ? g_World.Restock() : Restock(); break; case SEV_SEASON: SetSeason(static_cast<SEASON_TYPE>(s.GetArgVal())); break; case SEV_SLEEP: { if (IsSleeping()) { break; } if (!s.HasArgs())// with no args it will check if it can sleep before, to avoid possible problems. { if (!CanSleep(true)) { break; } } GoSleep(); } break; case SEV_SNOW: SetWeather( WEATHER_SNOW ); break; default: return( CScriptObj::r_Verb( s, pSrc )); } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_SCRIPTSRC; EXC_DEBUG_END; return false; }
bool CSector::OnTick() { ADDTOCALLSTACK("CSector::OnTick"); /*Ticking sectors from CWorld * Timer is automatically updated at the end with a 30 seconds default delay * Any return before it will threat this CSector as Sleep and will make it * not tick again until a new player enters (WARNING: even if there are * players already inside). */ EXC_TRY("Tick"); // do not tick sectors on maps not supported by server if ( !g_MapList.m_maps[m_map] ) return true; EXC_SET_BLOCK("light change"); // Check for light change before putting the sector to sleep, since in other case the // world light levels will be shitty bool fEnvironChange = false; bool fLightChange = false; // check for local light level change ? byte bLightPrv = m_Env.m_Light; m_Env.m_Light = GetLightCalc( false ); if ( m_Env.m_Light != bLightPrv ) { fEnvironChange = true; fLightChange = true; } EXC_SET_BLOCK("sector sleeping?"); bool fCanSleep = CanSleep(true); int64 iCurTime = CServerTime::GetCurrentTime().GetTimeRaw(); // Put the sector to sleep if no clients been here in a while. if (fCanSleep && (g_Cfg._iSectorSleepDelay > 0)) { if (!IsSleeping()) { GoSleep(); } return true; } EXC_SET_BLOCK("sound effects"); // random weather noises and effects. SOUND_TYPE sound = 0; bool fWeatherChange = false; int iRegionPeriodic = 0; WEATHER_TYPE weatherprv = m_Env.m_Weather; if ( ! Calc_GetRandVal( 30 )) // change less often { m_Env.m_Weather = GetWeatherCalc(); if ( weatherprv != m_Env.m_Weather ) { fWeatherChange = true; fEnvironChange = true; } } // Random area noises. Only do if clients about. if ( GetClientsNumber() > 0 ) { iRegionPeriodic = 2; static const SOUND_TYPE sm_SfxRain[] = { 0x10, 0x11 }; static const SOUND_TYPE sm_SfxWind[] = { 0x14, 0x15, 0x16 }; static const SOUND_TYPE sm_SfxThunder[] = { 0x28, 0x29 , 0x206 }; // Lightning ? // wind, rain, switch ( GetWeather() ) { case WEATHER_CLOUDY: break; case WEATHER_SNOW: if ( ! Calc_GetRandVal(5) ) sound = sm_SfxWind[ Calc_GetRandVal( CountOf( sm_SfxWind )) ]; break; case WEATHER_RAIN: { int iVal = Calc_GetRandVal(30); if ( iVal < 5 ) { // Mess up the light levels for a sec.. LightFlash(); sound = sm_SfxThunder[ Calc_GetRandVal( CountOf( sm_SfxThunder )) ]; } else if ( iVal < 10 ) sound = sm_SfxRain[ Calc_GetRandVal( CountOf( sm_SfxRain )) ]; else if ( iVal < 15 ) sound = sm_SfxWind[ Calc_GetRandVal( CountOf( sm_SfxWind )) ]; } break; default: break; } } // Check environ changes and inform clients of it. ProfileTask charactersTask(PROFILE_CHARS); CChar * pCharNext = nullptr; CChar * pChar = static_cast <CChar*>( m_Chars_Active.GetHead()); for ( ; pChar != nullptr; pChar = pCharNext ) { EXC_TRYSUB("TickChar"); pCharNext = pChar->GetNext(); if (( fEnvironChange ) && ( IsTrigUsed(TRIGGER_ENVIRONCHANGE) )) pChar->OnTrigger(CTRIG_EnvironChange, pChar); if ( pChar->IsClient()) { CClient * pClient = pChar->GetClient(); ASSERT( pClient ); if ( sound ) pClient->addSound(sound, pChar); if ( fLightChange && ! pChar->IsStatFlag( STATF_DEAD | STATF_NIGHTSIGHT )) pClient->addLight(); if ( fWeatherChange ) pClient->addWeather(GetWeather()); if ( iRegionPeriodic && pChar->m_pArea ) { if ( ( iRegionPeriodic == 2 ) && IsTrigUsed(TRIGGER_REGPERIODIC)) { pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_REGPERIODIC ); --iRegionPeriodic; } if ( IsTrigUsed(TRIGGER_CLIPERIODIC) ) pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_CLIPERIODIC ); } } EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventDebug("#0 char 0%x '%s'\n", (dword)(pChar->GetUID()), pChar->GetName()); g_Log.EventDebug("#0 sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; } ProfileTask overheadTask(PROFILE_OVERHEAD); EXC_SET_BLOCK("check map cache"); if (fCanSleep && m_iMapBlockCacheTime < iCurTime) // Only if the sector can sleep. { // delete the static CServerMapBlock items that have not been used recently. m_iMapBlockCacheTime = CServerTime::GetCurrentTime().GetTimeRaw() + g_Cfg.m_iMapCacheTime ; CheckMapBlockCache(); } EXC_CATCH; SetTimeoutS(30); // Sector is Awake, make it tick after 30 seconds. EXC_DEBUG_START; CPointMap pt = GetBasePoint(); g_Log.EventError("#4 sector #%d [%hd,%hd,%hhd,%hhu]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUG_END; return true; }
ApiManager::ApiAnswer * Bunny::ProcessVioletApiCall(HTTPRequest const& hRequest) { ApiManager::ApiViolet* answer = new ApiManager::ApiViolet(); if(hRequest.HasArg("sn") && hRequest.HasArg("token")) { QString serial = hRequest.GetArg("sn").toLower(); QString token = hRequest.GetArg("token"); if(GetGlobalSetting("VApiEnable",false).toBool()) { if((GetGlobalSetting("VApiToken","").toString() == token && serial.toAscii()==GetID()) || GetGlobalSetting("VApiPublic",false).toBool()) { if(hRequest.GetURI().startsWith("/ojn/FR/api_stream.jsp")) { if(hRequest.HasArg("urlList")) { QByteArray message = ("ST " + hRequest.GetArg("urlList").split("|", QString::SkipEmptyParts).join("\nMW\nST ") + "\nMW\n").toAscii(); SendPacket(MessagePacket(message)); answer->AddMessage("WEBRADIOSENT", "Your webradio has been sent"); } else { answer->AddMessage("NOCORRECTPARAMETERS", "Please check urlList parameter !"); } } else { AmbientPacket p; if(hRequest.HasArg("action")) // TODO: send good values { switch(hRequest.GetArg("action").toInt()) { case 2: answer->AddXml("<listfriend nb=\"0\"/>"); break; case 3: answer->AddXml("<listreceivedmsg nb=\"0\"/>"); break; case 4: answer->AddXml("<timezone>(GMT + 01:00) Bruxelles, Copenhague, Madrid, Paris</timezone>"); break; case 6: answer->AddXml("<blacklist nb=\"0\"/>"); break; case 7: if(IsSleeping()) answer->AddXml("<rabbitSleep>YES</rabbitSleep>"); else answer->AddXml("<rabbitSleep>NO</rabbitSleep>"); break; case 8: answer->AddXml("<rabbitVersion>V2</rabbitVersion>"); break; case 9: answer->AddXml("<voiceListTTS nb=\"2\"/><voice lang=\"fr\" command=\"FR-Anastasie\"/><voice lang=\"de\" command=\"DE-Otto\"/>"); break; case 10: answer->AddXml("<rabbitName>" + GetBunnyName() + "</rabbitName>"); break; case 11: answer->AddXml("<langListUser nb=\"4\"/><myLang lang=\"fr\"/><myLang lang=\"us\"/><myLang lang=\"uk\"/><myLang lang=\"de\"/>"); break; case 12: answer->AddXml("<message>LINKPREVIEW</message><comment>XXXX</comment>"); break; case 13: answer->AddXml("<message>COMMANDSENT</message><comment>You rabbit will change status</comment>"); SendPacket(SleepPacket(SleepPacket::Wake_Up)); break; case 14: answer->AddXml("<message>COMMANDSENT</message><comment>You rabbit will change status</comment>"); SendPacket(SleepPacket(SleepPacket::Sleep)); break; default: break; } } else { if(hRequest.HasArg("idmessage")) { answer->AddMessage("MESSAGESENT", "Your message has been sent"); } if(hRequest.HasArg("posleft") || hRequest.HasArg("posright")) { int left = 0; int right = 0; if(hRequest.HasArg("posleft")) left = hRequest.GetArg("posleft").toInt(); if(hRequest.HasArg("posright")) right = hRequest.GetArg("posright").toInt(); if(left >= 0 && left <= 16 && right >= 0 && right <= 16) { answer->AddMessage("EARPOSITIONSENT", "Your ears command has been sent"); p.SetEarsPosition(left, right); } else { answer->AddMessage("EARPOSITIONNOTSENT", "Your ears command could not be sent"); } } if(hRequest.HasArg("tts")) { SendPacket(MessagePacket("MU "+TTSManager::CreateNewSound(hRequest.GetArg("tts"), "claire")+"\nPL 3\nMW\n")); answer->AddMessage("TTSSENT", "Your text has been sent"); } if(hRequest.HasArg("ears")) { answer->AddEarPosition(0, 0); // TODO: send real positions } if(hRequest.HasArg("chor")) { Choregraphy c; if(c.Parse(hRequest.GetArg("chor"))) //TODO: Check for good chor { QDir chorFolder = QDir(GlobalSettings::GetString("Config/RealHttpRoot")); if (!chorFolder.cd("chor")) { if (!chorFolder.mkdir("chor")) { LogError(QString("Unable to create 'chor' directory !\n")); answer->AddMessage("CHORNOTSENT", "Your chor could not be sent (can't create folder)"); } chorFolder.cd("chor"); } QString fileName = QCryptographicHash::hash(c.GetData(), QCryptographicHash::Md5).toHex().append(".chor"); QString filePath = chorFolder.absoluteFilePath(fileName); QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { LogError("Cannot open chor file for writing"); answer->AddMessage("CHORNOTSENT", "Your chor could not be sent (error in file)"); } else { file.write(c.GetData()); file.close(); SendPacket(MessagePacket(("CH broadcast/ojn_local/chor/" + fileName + "\n").toAscii())); answer->AddMessage("CHORSENT", "Your chor has been sent"); } } else { answer->AddMessage("CHORNOTSENT", "Your chor could not be sent (bad chor)"); } } } if(p.GetServices().count() > 0) SendPacket(p); } } else { answer->AddMessage("NOGOODTOKENORSERIAL", "Your token or serial number are not correct !"); } } else { answer->AddMessage("APIDISABLED", "API is disabled for this bunny"); } } else { answer->AddMessage("APIDISABLED", "Missing serial or token"); } return answer; }