/// <summary> /// Main game loop for the server. /// </summary> void GameLoop() { ThreadAsserts.IsMainThread(); var updateServerTimeQuery = DbController.GetQuery <UpdateServerTimeQuery>(); var serverTimeUpdater = new ServerTimeUpdater(updateServerTimeQuery); // Set the initial auto-save time _nextServerSaveTime = GetTime() + ServerSettings.Default.RoutineServerSaveRate; var worldStatsTracker = WorldStatsTracker.Instance; while (IsRunning) { // Store the loop start time so we can calculate how long the loop took var loopStartTime = GetTime(); // Update the networking ServerSockets.Heartbeat(); // Update the world _world.Update(); // Update the time serverTimeUpdater.Update(GetTime()); // Handle the queued console commands ProcessConsoleCommands(); // Check if it is time to save the world if (_nextServerSaveTime < loopStartTime) { ServerSave(); } // Update the world stats worldStatsTracker.Update(); // Check if we can afford sleeping the thread var updateElapsedTime = (long)GetTime() - loopStartTime; var sleepTime = ServerSettings.Default.ServerUpdateRate - updateElapsedTime; if (sleepTime > 0) { Thread.Sleep((int)sleepTime); } ++_tick; } // Once the thread reaches this point, it means it is closing since the main loop has stopped // Update the world stats and events one last time before the server closes worldStatsTracker.Update(); EventCounterManager.FlushAll(); // Dispose if (ServerSockets != null) { ServerSockets.Shutdown(); } if (World != null) { World.Dispose(); } if (DbController != null) { DbController.Dispose(); } }
//==================================================================================================== /// <summary> /// dispose. /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { this.disposed = true; if (disposing) { // // call .dispose for managed objects // // ----- Block all output from underlying routines // doc.blockExceptionReporting = true; doc.continueProcessing = false; // // content server object is valid // if (serverConfig != null) { if (appConfig != null) { if (appConfig.appStatus == AppConfigBaseModel.AppStatusEnum.ok) { if (deleteSessionOnExit) { if ((session != null)) { if ((session.visit != null) && (session.visit.id > 0)) { // // -- delete visit visitProperty.deleteAll(session.user.id); DbBaseModel.delete <VisitModel>(cpParent, session.visit.id); // // -- delete viewing DbBaseModel.deleteRows <ViewingModel>(cpParent, "(visitId=" + session.visit.id + ")"); } if ((session.visitor != null) && (session.visitor.id > 0)) { // // -- delete visitor visitorProperty.deleteAll(session.user.id); DbBaseModel.delete <VisitorModel>(cpParent, session.visit.id); } } } if (!deleteSessionOnExit && siteProperties.allowVisitTracking) { // // If visit tracking, save the viewing record // string ViewingName = ((string)(session.visit.id + "." + session.visit.pageVisits)).left(10); int PageId = 0; if (_doc != null) { if (doc.pageController.page != null) { PageId = doc.pageController.page.id; } } // // -- convert requestForm to a name=value string for Db storage string requestFormSerialized = GenericController.convertNameValueDictToREquestString(webServer.requestForm); string pagetitle = ""; if (!doc.htmlMetaContent_TitleList.Count.Equals(0)) { pagetitle = doc.htmlMetaContent_TitleList[0].content; } string sql = "insert into ccviewings (" + "Name,VisitId,MemberID,Host,Path,Page,QueryString,Form,Referer,DateAdded,StateOK,pagetime,Active,RecordID,ExcludeFromAnalytics,pagetitle,ccguid" + ")values(" + " " + DbController.encodeSQLText(ViewingName) + "," + session.visit.id.ToString() + "," + session.user.id.ToString() + "," + DbController.encodeSQLText(webServer.requestDomain) + "," + DbController.encodeSQLText(webServer.requestPath) + "," + DbController.encodeSQLText(webServer.requestPage) + "," + DbController.encodeSQLText(webServer.requestQueryString.left(255)) + "," + DbController.encodeSQLText(requestFormSerialized.left(255)) + "," + DbController.encodeSQLText(webServer.requestReferrer.left(255)) + "," + DbController.encodeSQLDate(doc.profileStartTime) + "," + DbController.encodeSQLBoolean(session.visitStateOk) + "," + doc.appStopWatch.ElapsedMilliseconds.ToString() + ",1" + "," + PageId.ToString() + "," + DbController.encodeSQLBoolean(webServer.pageExcludeFromAnalytics) + "," + DbController.encodeSQLText(pagetitle) + "," + DbController.encodeSQLText(doc.docGuid); sql += ");"; Task.Run(() => db.executeNonQueryAsync(sql)); } } } } // // ----- dispose objects created here // if (_addon != null) { _addon.Dispose(); _addon = null; } // if (_db != null) { _db.Dispose(); _db = null; } // if (_cache != null) { _cache.Dispose(); _cache = null; } // if (_db != null) { _db.Dispose(); _db = null; } // _siteProperties = null; _domains = null; _docProperties = null; _webServer = null; _visitProperty = null; _visitorProperty = null; _userProperty = null; } // // cleanup non-managed objects // } }