using System;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using Woodpecker.Core;
using Woodpecker.Storage;
using Woodpecker.Specialized;
using Woodpecker.Security.Cryptography;
using Woodpecker.Net.Game;
using Woodpecker.Net.Remote;
using Woodpecker.Sessions;
using Woodpecker.Game.Externals;
using Woodpecker.Game.Users;
using Woodpecker.Game.Users.Roles;
using Woodpecker.Game.Store;
using Woodpecker.Game.Messenger;
using Woodpecker.Game.Moderation;
using Woodpecker.Game.Rooms;
using Woodpecker.Game.Items;
using Woodpecker.Game.Arcade;
namespace Woodpecker
{
///
/// The 'hearth' of Woodpecker, containing references to all kinds of objects.
///
public static class Engine
{
#region Fields
private static bool mGotLicense = false;
private static mainForm mMainForm;
private static sessionManager mSessionManager = new sessionManager();
private static gameConnectionManager mGameConnectionManager = new gameConnectionManager();
private static remoteConnectionManager mRemoteConnectionManager = new remoteConnectionManager();
private static externalManager mExternalManager = new externalManager();
private static userManager mUserManager = new userManager();
private static roleManager mRoleManager = new roleManager();
private static storeManager mStoreManager = new storeManager();
private static messengerManager mMessengerManager = new messengerManager();
private static moderationManager mModerationManager = new moderationManager();
private static roomManager mRoomManager = new roomManager();
private static itemManager mItemManager = new itemManager();
private static arcadeManager mArcadeManager = new arcadeManager();
private static md5Provider mMD5Provider = new md5Provider();
#endregion
#region Properties
public static class Program
{
#region Properties
///
/// Gets the license status of this copy of Woodpecker as a boolean.
///
public static bool isLicensed
{
get { return mGotLicense; }
}
///
/// A reference to the main form with the user interface.
///
public static mainForm GUI
{
get { return mMainForm; }
set { mMainForm = value; }
}
///
/// The product version of this copy of Woodpecker as a string.
///
public static string Version
{
get { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
}
#endregion
#region Methods
///
/// Starts the booting procedure of Woodpecker and handles exceptions.
///
public static void Start()
{
Logging.setDefaultLogSessings();
Logging.Log("Woodpecker v" + Version);
Logging.Log(null);
Logging.Log("Checking db.config...");
if (!Configuration.configFileExists)
{
Logging.Log("db.config was not found in the same directory as the executable of this copy of Woodpecker!");
Stop("db.config not found");
return;
}
Configuration.createConnectionString();
Logging.Log("Running database connectivity check...");
Database Check = new Database(true, true);
if (Check.Ready)
{
Check.runQuery("INSERT INTO server_startups(startup) VALUES (NOW())"); // Log server startup
Check = null;
Logging.Log("Database is contactable!");
}
else
{
Logging.Log("Failed to contact database, please check the error shown above!", Logging.logType.commonWarning);
Stop("failed to contact database");
return;
}
Logging.Log(null);
Configuration.loadConfiguration();
mMD5Provider = new md5Provider();
mMD5Provider.baseSalt = Configuration.getConfigurationValue("cryptography.md5.salt");
mExternalManager.loadEntries();
mRoleManager.loadRoles();
mMessengerManager.setConfiguration();
mModerationManager.logChat = (Configuration.getConfigurationValue("moderation.logchat") == "1");
mItemManager.loadDefinitions();
mStoreManager.loadSales();
mStoreManager.loadCataloguePages();
mRoomManager.initRoomCategories();
mRoomManager.initRoomModels();
int Port = Configuration.getNumericConfigurationValue("connections.game.port");
if (Port > 0)
{
int maxConnectionsPerIP = Configuration.getNumericConfigurationValue("connections.game.maxperip");
if (maxConnectionsPerIP == 0)
{
Logging.Log("The field connections.game.maxperip in the `configuration` table of the database is not holding a valid value. The default value '3' will be used.", Logging.logType.commonWarning);
maxConnectionsPerIP = 3;
}
if (!mGameConnectionManager.startListening(Port, maxConnectionsPerIP))
{
Logging.Log("Failed to setup game connection listener, the port (" + Port + ") is probably in use by another application.", Logging.logType.commonWarning);
Stop("failed to setup game connection listener");
return;
}
}
else
{
Logging.Log("The field 'connections.game.port' in the `configuration` table of the database is not present. Please fill in a numeric entry, which represents the port to listen on for game connections.", Logging.logType.commonWarning);
Stop("No valid port for game connection listener set.");
return;
}
Port = 3080;
if (Port > 0)
{
bool allowExternalHosts = false;
if (!mRemoteConnectionManager.startListening(Port, allowExternalHosts))
{
Logging.Log("Failed to setup remote connection listener, the port (" + Port + ") is probably in use by another application.", Logging.logType.commonWarning);
Stop("failed to setup remote connection listener");
return;
}
}
mSessionManager.startPingChecker();
mSessionManager.startReceivedBytesChecker();
Game.startUpdater();
Logging.Log(null);
Logging.Log("Ready.");
mMainForm.logSacredText(null);
mMainForm.stripMenu.Enabled = true;
}
///
/// Sets Woodpecker in the 'allowed to close window'-mode, after shutting down all other tasks etc. A message is being displayed with the reason of shutdown.
///
/// The reason of the shutdown.
public static void Stop(string Message)
{
Logging.Log("Shutting down, reason: " + Message);
mGameConnectionManager.stopListening();
mSessionManager.stopPingChecker();
mSessionManager.stopMessageSizeChecker();
mSessionManager.Clear();
//_roomManager.saveInstances();
Game.stopUpdater();
mMainForm.stripMenu.Enabled = false;
mMainForm.mShutdown = true;
Logging.Log("Woodpecker safely shutdown! You can now close the application.");
}
#endregion
}
///
/// Provides various functions for enciphering and hashing data.
///
public static class Security
{
///
/// Provides functions for hashing data.
///
public static class Cryptography
{
public static md5Provider MD5
{
get { return mMD5Provider; }
}
}
///
/// Provides functions for ciphering data and generating public keys. Also features a factory for creating RC4 classes.
///
public static class Ciphering
{
///
/// Generates a total random public key with a random length for the RC4 ciphering, containing a-z and 0-9 and returns it as a string.
///
public static string generateKey()
{
int keyLength = new Random(DateTime.Now.Millisecond).Next(60, 65);
Random v = new Random(DateTime.Now.Millisecond + DateTime.Now.Second + keyLength);
StringBuilder sb = new StringBuilder(keyLength);
for (int i = 0; i < keyLength; i++)
{
int j = 0;
if (v.Next(0, 2) == 1)
j = v.Next(97, 123);
else
j = v.Next(48, 58);
sb.Append((char)j);
}
return sb.ToString();
}
}
}
///
/// Provides various functions regarding player sessions.
///
public static sessionManager Sessions
{
get { return mSessionManager; }
}
///
/// Provides various functions for connections.
///
public static class Net
{
///
/// Provides various functions for game connections.
///
public static gameConnectionManager Game
{
get { return mGameConnectionManager; }
}
///
/// Provides various functions for remote connections.
///
public static remoteConnectionManager Remote
{
get { return mRemoteConnectionManager; }
}
}
///
/// Provides management for all kinds of in-game related things.
///
public static class Game
{
#region Properties
private static Thread mUpdateWorker;
///
/// Provides management for cached external texts.
///
public static externalManager Externals
{
get { return mExternalManager; }
}
///
/// Provides management and functions for logged in users, user data etc.
///
public static userManager Users
{
get { return mUserManager; }
}
///
/// Provides management and functions for user roles, such as rights, badges etc.
///
public static roleManager Roles
{
get { return mRoleManager; }
}
///
/// Contains various functions and fields for the catalogue and it's items, as well as other financial things.
///
public static storeManager Store
{
get { return mStoreManager; }
}
///
/// Provides various functions for the in-game messenger ('Console') for sending messages to users, adding users to buddylist etc. Also features a postmaster.
///
public static messengerManager Messenger
{
get { return mMessengerManager; }
}
///
/// Provides all kinds of functions for moderation in the virtual hotel, eg, bans etc.
///
public static moderationManager Moderation
{
get { return mModerationManager; }
}
///
/// Provides all kinds of functions for rooms, room categories and the navigator.
///
public static roomManager Rooms
{
get { return mRoomManager; }
}
public static itemManager Items
{
get { return mItemManager; }
}
public static arcadeManager Arcade
{
get { return mArcadeManager; }
}
#endregion
#region Methods
///
/// Attempts to start the game updater worker thread.
///
public static void startUpdater()
{
if(mUpdateWorker == null)
{
mUpdateWorker = new Thread(new ThreadStart(Updater));
mUpdateWorker.Start();
Logging.Log("Game update worker started.");
Rooms.resetRoomUserAmounts();
}
}
///
/// Stops the game updater worker thread.
///
public static void stopUpdater()
{
if (mUpdateWorker != null)
{
mUpdateWorker.Abort();
mUpdateWorker = null;
Logging.Log("Game update worker stopped.");
}
}
///
/// An infinite loop at a configured interval, updating various things in game.
///
private static void Updater()
{
while (true)
{
Moderation.dropExpiredBans();
Messenger.Postmaster.dropInvalidMessages();
Rooms.dropInvalidFavoriteRoomEntries();
Rooms.destroyInactiveRoomInstances();
GC.Collect(); // Force garbage collecting
Thread.Sleep(3 * 60000); // 3 minutes interval
}
}
#endregion
}
#endregion
}
}