Skip to content

Instantly share code, notes, and snippets.

@rarous
Created July 24, 2014 17:34
Show Gist options
  • Save rarous/965d5fcf3a1facbe50da to your computer and use it in GitHub Desktop.
Save rarous/965d5fcf3a1facbe50da to your computer and use it in GitHub Desktop.
#define LOG
using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Collections;
using System.Data.SqlClient;
using Atlas.Pokec.DataObjects;
using Atlas.Pokec.DataObjects.Messages;
namespace Atlas.Pokec.DataService
{
/// <summary>
/// Objekt na zasilani prikazu
/// </summary>
public class CommandSender : BinaryWriter
{
#region Members
private Socket sock;
/// <summary>
/// Vytvori objekt na zasilani commandu
/// </summary>
/// <param name="socket">Socket pro odpoved</param>
/// <param name="id">Cislo odpovedni zpravy</param>
/// <param name="size">Delka dat (jen pro optimalizaci)</param>
public CommandSender(Socket socket,ushort id,int size) : base(new MemoryStream(size+2))
{
sock=socket;
Write(id);
Write((int)0);
}
/// <summary>
/// Odeslat data
/// </summary>
public void SendCommand()
{
// ziskat buffer a vlozit do nej delku dat
byte[] buffer=((MemoryStream)OutStream).ToArray();
new BinaryWriter(new MemoryStream(buffer,2,4,true)).Write
(buffer.Length-ClientConnection.CommandLength);
// odeslat
sock.Send(buffer);
this.Close();
}
#endregion
}
/// <summary>
/// Zajistuje komunikaci s pripojenym webovym serverem
/// </summary>
public class ClientConnection
{
#region Variables & Constants
public const int CommandLength=6;
internal Socket socket;
internal bool connected;
byte[] cmdBuffer;
int cmdReceived=0;
int dataReceived=0;
#endregion
#region Variables used by ProcessCommand
/// <summary> Buffer s dalsima datama ke zprave </summary>
byte[] dataBuffer;
/// <summary> Id commandu </summary>
ushort command;
/// <summary> Delka user dat </summary>
int dataLength;
/// <summary> Objekt serveru </summary>
TcpServer serverObj;
#endregion
#region Constructor
/// <summary>
/// Vytvori objekt pro novy akceptovany socket
/// </summary>
/// <param name="server">Server</param>
/// <param name="sock">Novy socket</param>
public ClientConnection(TcpServer server,Socket sock)
{
serverObj=server;
connected=true;
socket=sock;
cmdBuffer=new byte[CommandLength];
}
#endregion
#region Methods for receiving data
/// <summary>
/// Spustit komunikaci
/// </summary>
public void Start()
{
SetupReceiveCommand();
}
/// <summary>
/// Nastavi asynchroni prijem commandu
/// </summary>
private void SetupReceiveCommand()
{
socket.BeginReceive(cmdBuffer,cmdReceived,CommandLength-cmdReceived,
SocketFlags.None,new AsyncCallback(CmdReceivedHandler),this);
}
/// <summary>
/// Nastavi asynchroni prijem dalsich dat
/// </summary>
private void SetupReceiveData()
{
BinaryReader br=new BinaryReader(new MemoryStream(cmdBuffer));
command=br.ReadUInt16();
dataLength=br.ReadInt32();
if (dataLength==0)
{
ProcessCommand();
}
else
{
dataBuffer=new byte[dataLength];
dataReceived=0;
socket.BeginReceive(dataBuffer,dataReceived,dataLength-dataReceived,
SocketFlags.None,new AsyncCallback(DataReceivedHandler),this);
}
}
/// <summary>
/// Je prijata cela hlavicka commandu?
/// </summary>
private bool CommandReceived
{
get { return cmdReceived==CommandLength; }
}
/// <summary>
/// Jsou prijata vsechna user data ke zprave?
/// </summary>
private bool DataReceived
{
get { return dataReceived==dataLength; }
}
/// <summary>
/// Prijimani commandu (metoda se vola po skonceni async. volani)
/// </summary>
/// <param name="result">Vysledek volani</param>
private void CmdReceivedHandler(IAsyncResult result)
{
try
{
int bytesRead=socket.EndReceive(result);
if (bytesRead>0)
{
cmdReceived+=bytesRead;
if (!CommandReceived)
SetupReceiveCommand();
else
SetupReceiveData();
}
// ukoncit komunikaci
if (bytesRead==0)
{
command=0;
ProcessCommand();
}
}
catch(Exception e)
{
#region Handle exception
#if LOG
WriteLog("Oops (CmdReceivedHandler)! Command:{0}\nException:\n{1}",command,e.ToString());
#endif
serverObj.eventLog.WriteEntry(string.Format("Unhandled exception in ProcessCommand\nCommand={0}\n\n{1}",
command.ToString(),e.ToString()));
#endregion
}
}
/// <summary>
/// Prijimani dat zpravy (metoda se vola po skonceni async. volani)
/// </summary>
/// <param name="result">Vysledek volani</param>
private void DataReceivedHandler(IAsyncResult result)
{
int bytesRead=socket.EndReceive(result);
if (bytesRead>0)
{
dataReceived+=bytesRead;
if (!DataReceived)
SetupReceiveData();
else
ProcessCommand();
}
}
#endregion
#region Private methods
/// <summary>
/// Zjistuje jestli uzivatel ma pravo vstoupit do mistnosti
/// </summary>
/// <param name="room">Mistnost</param>
/// <param name="user">Uzivatel</param>
/// <returns>0 = ok; 1 = ne; 2 = chceme heslo</returns>
/// <param name="adult">Je dospelej??</param>
/// <param name="pass">Heslo</param>
private byte GetRoomAccess(RoomInfo room,UserInfo user,string pass,bool adult)
{
// bool deleted, int maxnicks, int attributes, string password
SqlDataReader reader=Database.Rooms.GetRoomSettings(room.ID);
byte ret=0;
if (!reader.Read()) { reader.Close(); return 1; }
if (reader.GetBoolean(0)) ret=1;
// admina uz pustime
if (user.Rights.HasRights(RightsEnum.AllowEnterLockedRoom))
{ reader.Close(); return 0; }
// vsechny kontroly
if (reader.GetString(3)!=pass) ret=2;
if (reader.GetInt32(1)!=0&&reader.GetInt32(1)<=room.Users.Count) ret=1;
RoomSettingsEnum ra=(RoomSettingsEnum)reader.GetInt32(2);
if ((ra&RoomSettingsEnum.Locked)>0) ret=1;
if ((ra&RoomSettingsEnum.BanHosts)>0&&user.IsHost) ret=1;
if ((ra&RoomSettingsEnum.OnlyAdmins)>0&&!user.Rights.HasAnyRights()) ret=1;
if ((ra&RoomSettingsEnum.OnlyFemales)>0&&user.IsMale) ret=1;
if ((ra&RoomSettingsEnum.OnlyMales)>0&&user.IsFemale) ret=1;
if ((ra&RoomSettingsEnum.OnlyAdults)>0&&!adult) ret=1;
return ret;
}
/// <summary>
/// Odejit z mistnosti
/// </summary>
/// <param name="room">Info o mistnosti</param>
/// <param name="user">Id uzivatele</param>
/// <param name="userInfo">Info o uzivateli</param>
private void TryLeaveRoom(RoomInfo room,Guid user,UserInfo userInfo)
{
if (!room.Users.ContainsKey(user)) return;
room.Users.Remove(user);
// systemova zprava do mistnosti
room.Messages.Add(new SysMessage(Guid.Empty,
serverObj.langManager.GetText(room.Language,"system-name"),
String.Format(serverObj.langManager.GetText(room.Language,
userInfo.IsMale?"user-m-leftroom":"user-f-leftroom"),userInfo.Name)),true);
// uz tu nikdo neni toz to smazat! (samozrejme jen docasny ale to resi DB)
if (room.Users.Count==0)
{
Database.Rooms.DeleteRoomNotPermanent(room.ID,room.UsersCount);
}
}
/// <summary>
/// Vraci mistnost s danym IDckem
/// </summary>
/// <param name="roomId">Idcko</param>
/// <returns>Mistnost</returns>
private RoomInfo GetRoom(int roomId)
{
RoomInfo room=(RoomInfo)serverObj.roomsList[roomId];
if (room==null)
{
serverObj.roomsList.UpdateRooms(Database.Rooms.SelectRooms());
room=(RoomInfo)serverObj.roomsList[roomId];
}
return room;
}
#endregion
// Hlavni metoda, ktera zpracovava komunikaci s klienty
#region ProcessCommand
/// <summary>
/// Zpracovat prikaz
/// </summary>
private void ProcessCommand()
{
try
{
#if LOG
if (command!=0) WriteLog("Command: {0:x}",command);
#endif
#region if (command==Commands.Close) Ukoncit komunikaci a uzavrit spojeni
if (command==Commands.Close)
{
serverObj.RemoveClient(this);
return;
}
#endregion
// uzivatele atd..
#region if (command==Commands.SendUsersList) Poslat seznam vsech online lidi
/*
if (command==Commands.SendUsersList)
{
CommandSender ret=new CommandSender(socket,Commands.ResponseSendUsersList,
8+serverObj.usersList.Length*16);
ret.Write(serverObj.usersList.Length);
Hashtable temp=new Hashtable(serverObj.usersList.Length);
foreach(UserInfo usr in serverObj.usersList)
temp.Add(usr.Id,usr);
foreach(RoomInfo room in serverObj.roomsList)
{
foreach(UserInfo user in room.Users.Values)
{
temp.Remove(user.Id);
ret.Write(user.Id.ToByteArray());
ret.Write(room.ID);
ret.Write(user.RenderName(room.ID));
ret.Write(user.Rights.HasAnyRights(room.ID));
}
}
foreach(UserInfo user in temp.Values)
{
ret.Write(user.Id.ToByteArray());
ret.Write(-1);
ret.Write(user.RenderName(-1));
ret.Write(user.Rights.HasAnyRights(-1));
}
ret.SendCommand();
}
*/
#endregion
#region if (command==Commands.SendHostId) Poslat klientovi nove Id hosta
if (command==Commands.SendHostId)
{
CommandSender ret=new CommandSender(socket,Commands.ResponseHostId,4);
ret.Write(UserInfo.NextHostId);
ret.SendCommand();
}
#endregion
#region if (command==Commands.LoginUser) Prihlasit nove pripojeneho nicka
/*
if (command==Commands.LoginUser)
{
BinaryReader reader=new BinaryReader(new MemoryStream(dataBuffer));
UserInfo usr=UserInfo.Load(reader);
Guid mpId=new Guid(reader.ReadBytes(16));
#if LOG
WriteLog("Login user: {0} ({1})",usr.Name,usr.Id);
#endif
CommandSender ret=new CommandSender(socket,Commands.ResponseLoginUser,4);
// test jestli nahodou neni blokovany
int retVal=serverObj.banManager.BannedLogin(usr.HostAddress,mpId,usr.Id);
ret.Write(retVal);
if (retVal==0)
{
// pokud je prihlaseny - odhlasit
if (serverObj.usersList[usr.Id]!=null)
{
UserInfo user=(UserInfo)serverObj.usersList[usr.Id];
serverObj.usersList.Remove(usr.Id);
foreach(RoomInfo room in serverObj.roomsList)
TryLeaveRoom(room,usr.Id,user);
}
serverObj.usersList.Add(usr);
#if LOG
WriteLog("Login user - success");
#endif
}
ret.SendCommand();
}
*/
#endregion
#region if (command==Commands.LogoutUser) Odhlasit prihlaseneho nicka
/*
if (command==Commands.LogoutUser)
{
Guid id=new Guid(dataBuffer);
UserInfo user=(UserInfo)serverObj.usersList[id];
#if LOG
WriteLog("Logout user: {0} ({1})",user==null?"(null)":user.Name,id);
#endif
serverObj.usersList.Remove(id);
foreach(RoomInfo room in serverObj.roomsList)
TryLeaveRoom(room,id,user);
}
*/
#endregion
// mistnosti (vstupovani atd..)
#region if (command==Commands.TryEnterRoom) Vstoupit do mistnosti
if (command==Commands.TryEnterRoom)
{
// nacist data pro vstup do mistnosti
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
UserInfo user=UserInfo.Load(br);
int roomId=br.ReadInt32();
string pass=br.ReadString();
user.IsBold=br.ReadBoolean();
#if LOG
WriteLog("Enter room; room={0} (exists={1}); user={2}",roomId,GetRoom(roomId)!=null,user.Name);
#endif
// zjistit objekt mistnosti a jestli tam uzivatel smi vstoupit
RoomInfo room=GetRoom(roomId);
// Zjistit jestli na to uzivatel ma prava...
byte access=1;
int moreData=0;
if (room!=null&&user!=null)
{
// blokovany login (ip .. atd)
if (serverObj.banManager.BannedLogin(user.HostAddress,Guid.Empty,user.Id)==0)
{
// blokovany vstup do mistnosti
moreData=serverObj.banManager.BannedRoomEnter(roomId,user.Id);
if (moreData>0)
access=4;
else
access=GetRoomAccess(room,user,pass,user.IsAdult);
if (access==0)
{
// pridat uzivatele
if (!room.Users.ContainsKey(user.Id))
room.Users.Add(user.Id,user);
// uzivatel vstoupil do mistnosti...
room.Messages.Add(new SysMessage(Guid.Empty,serverObj.langManager.
GetText(room.Language,"system-name"),String.Format(
serverObj.langManager.GetText(room.Language,
user.IsMale?"user-m-enterroom":"user-f-enterroom"),user.Name)),true);
// welcome message pro usera
if (room.EnterMessage!="")
room.Messages.Add(new SysMessage(user.Id,serverObj.langManager.
GetText(room.Language,"system-name"),room.EnterMessage),true);
room.UsersCount++;
}
}
}
CommandSender ret=new CommandSender(socket,Commands.ResponseTryEnterRoom,4);
ret.Write(access);
if (access==4) ret.Write(moreData);
ret.SendCommand();
}
#endregion
#region if (command==Commands.SendRoomUsers) Poslat uzivatele (nicky v mistnosti)
if (command==Commands.SendRoomUsers)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
RoomInfo room=GetRoom(roomId);
// ted uz opravdu odpovedet
if (room==null)
{
// tohle by se nemelo stavat....
CommandSender ret=new CommandSender(socket,Commands.ResponseSendRoomUsers,4);
ret.Write((Int32)0); ret.SendCommand();
}
else
{
// odpoved
CommandSender ret=new CommandSender(socket,Commands.ResponseSendRoomUsers,
room.Users.Count*64);
room.SaveUsers(ret,roomId);
ret.SendCommand();
}
}
#endregion
#region if (command==Commands.LeaveRoom) Opustit mistnost
if (command==Commands.LeaveRoom)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
Guid user=new Guid(br.ReadBytes(16));
int roomId=br.ReadInt32();
RoomInfo room=GetRoom(roomId);
UserInfo userInfo=(UserInfo)room.Users[user];
#if LOG
WriteLog("Leave room; room={0} (exists={1}); user={2} ({3})",roomId,GetRoom(roomId)!=null,
user,userInfo==null?"(null)":userInfo.Name);
#endif
TryLeaveRoom(room,user,userInfo);
}
#endregion
#region if (command==Commands.ReloadSettings) Donutit mistnost aby znovu nacetla sve nastaveni
if (command==Commands.ReloadSettings)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
GetRoom(br.ReadInt32()).ReloadSettings();
}
#endregion
// prikazy
#region if (command==Commands.KickUser) Vykopnout zleho uzivatele
/*
if (command==Commands.KickUser)
{
// nacist data z commandu
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
Guid user=new Guid(br.ReadBytes(16));
Guid adminId=new Guid(br.ReadBytes(16));
bool bHardKick=br.ReadBoolean();
string reason=br.ReadString().Trim();
RoomInfo room=GetRoom(roomId);
UserInfo userInfo=(UserInfo)room.Users[user];
#if LOG
WriteLog("Kick user; room={0} (exists={1}); user={2} ({3}); reason={4}",
roomId,room!=null,user,userInfo==null?"(null)":userInfo.Name,reason);
#endif
// nacist admina a zkontrolovat prava
string adminName="";
bool bCanBeKicked=!userInfo.Rights.HasAnyRights(roomId);
if (adminId!=Guid.Empty)
{
UserInfo admin=(UserInfo)serverObj.usersList[adminId];
adminName=admin.Name;
// cerveny
if (userInfo.Rights.HasRights(RightsEnum.SuperAdmin))
bCanBeKicked=false;
else if (admin.Rights.HasRights(RightsEnum.SuperAdmin))
bCanBeKicked=true;
else
{ // necerveny
// modry muzou zase vse (krom kickani sebe)
if (userInfo.Rights.HasRights(RightsEnum.Kick)||
userInfo.Rights.HasRights(RightsEnum.HardKick))
bCanBeKicked=false;
else if (admin.Rights.HasRights(RightsEnum.Kick)||
admin.Rights.HasRights(RightsEnum.HardKick))
bCanBeKicked=true;
else
{
// zeleny nebo boldi
if (userInfo.Rights.HasRights(RoomRightsEnum.Kick,roomId))
bCanBeKicked=true;
else if (admin.Rights.HasRights(RoomRightsEnum.Kick,roomId))
bCanBeKicked=true;
else
{
bCanBeKicked=false;
// boldi
//if (userInfo.BoldAdminRoom==roomId)
// bCanBeKicked=false;
//else if (userInfo.BoldAdminRoom==roomId)
// bCanBeKicked=true;
}
}
}
}
if (!bCanBeKicked&&adminId!=Guid.Empty&&room!=null)
{
room.Messages.Add(new SysMessage(user,
serverObj.langManager.GetText(room.Language,"system-name"),
string.Format(serverObj.langManager.GetText(room.Language,"admin-tried-to-kick-you"),adminName)),true);
room.Messages.Add(new SysMessage(adminId,
serverObj.langManager.GetText(room.Language,"system-name"),
serverObj.langManager.GetText(room.Language,"insufficient-rights")),true);
}
if (bCanBeKicked&&userInfo!=null)
{
// na jak dlouho bude kickly
int minutes=10;
char c2=reason.Length>=1?reason[reason.Length-1]:' ',
c1=reason.Length>=2?reason[reason.Length-2]:' ';
if (c1>='0'&&c1<='9')
{
if (c2>='0'&&c2<='9')
{
minutes=Int32.Parse(new string(new char[] {c1,c2}));
reason=reason.Substring(0,reason.Length-2);
}
}
else
{
if (c2>='0'&&c2<='9')
{
minutes=(int)(c2-'0');
reason=reason.Substring(0,reason.Length-1);
}
}
// nacist z mistnosti duvod
if (reason==""||reason=="kicked-by-system")
{
if (reason=="") reason="default-kick-reason";
reason=serverObj.langManager.GetText(room.Language,reason);
}
room.Users.Remove(user);
// systemova zprava do mistnosti
string msg;
if (adminName!="")
msg=String.Format(serverObj.langManager.GetText
(room.Language,userInfo.IsMale?"user-m-kicked-by-admin":"user-f-kicked-by-admin"),
userInfo.Name,adminName,reason);
else
msg=String.Format(serverObj.langManager.GetText(room.Language,
userInfo.IsMale?"user-m-kicked-by-system":"user-f-kicked-by-system"),userInfo.Name);
room.Messages.Add(new SysMessage(Guid.Empty,serverObj.langManager.GetText(room.Language,"system-name"),msg),true);
room.KickUser(user,adminName,reason);
serverObj.banManager.BanRoomEnter(bHardKick?-1:roomId,user,minutes);
// uz tu nikdo neni toz to smazat! (samozrejme jen docasny ale to resi DB)
if (room.Users.Count==0)
{
Database.Rooms.DeleteRoomNotPermanent(room.ID,room.UsersCount);
}
}
}
*/
#endregion
#region if (command==Commands.GetKickReason) Zjistit proc byl uzivatel vykopnut
if (command==Commands.GetKickReason)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
Guid user=new Guid(br.ReadBytes(16));
RoomInfo room=GetRoom(roomId);
#if LOG
WriteLog("Get kick reason; room={0}; user={1}",roomId,user);
#endif
// poslat odpoved
CommandSender ret=new CommandSender(socket,Commands.ResponseGetKickReason,100);
room.GetKickReason(user).Save(ret);
ret.Write(serverObj.banManager.BannedRoomEnter(roomId,user));
ret.SendCommand();
}
#endregion
#region if (command==Commands.MessengerSend) Posila zpravu do mistnosi nebo na cely pokec
if (command==Commands.MessengerSend)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
string message=br.ReadString();
// do vsech mistnosti
if (roomId==-1)
{
foreach(RoomInfo room in serverObj.roomsList)
room.Messages.Add(new MsgrMessage(Guid.Empty,Guid.Empty,"",
serverObj.langManager.GetText(room.Language,"messenger-name"),message),true);
}
// jen do jedne mistnost
else
{
RoomInfo room=GetRoom(roomId);
room.Messages.Add(new MsgrMessage(Guid.Empty,Guid.Empty,"",
serverObj.langManager.GetText(room.Language,"messenger-name"),message),true);
}
}
#endregion
#region if (command==Commands.TellMessenge) Posila zpravu uzivateli mezi mistnostma
/*
if (command==Commands.TellMessage)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
Guid fromId=new Guid(br.ReadBytes(16));
string origUserName=br.ReadString();
string userName=origUserName.ToLower();
string message=br.ReadString();
RoomInfo fromRoom=GetRoom(roomId);
string fromName=((UserInfo)fromRoom.Users[fromId]).Name;
// do vsech mistnosti
Guid toId=Guid.Empty;
foreach(UserInfo user in serverObj.usersList)
{
if (user.Name.ToLower()==userName)
{ toId=user.Id; break; }
}
if (toId==Guid.Empty)
{
fromRoom.Messages.Add(new SysMessage(fromId,
serverObj.langManager.GetText(fromRoom.Language,"system-name"),
string.Format(serverObj.langManager.GetText(fromRoom.Language,"user-notfound"),origUserName)),true);
}
else
{
foreach(RoomInfo room in serverObj.roomsList)
{
room.Messages.Add(new MsgrMessage(toId,fromId,origUserName,fromName,message),true);
}
}
}
*/
#endregion
#region if (command==Commands.BanManagerCommand) Blokovat nebo odblokovat IP,MiniPas nebo Nick
if (command==Commands.BanManagerCommand)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int iBlock=br.ReadInt32();
byte cmd=br.ReadByte();
switch(cmd)
{
case 0:
if (iBlock>0)
serverObj.banManager.BanIPLogin(br.ReadString(),iBlock);
else
serverObj.banManager.AllowIPLogin(br.ReadString());
break;
case 1:
if (iBlock>0)
serverObj.banManager.BanMiniPasLogin(new Guid(br.ReadBytes(16)),iBlock);
else
serverObj.banManager.AllowMiniPasLogin(new Guid(br.ReadBytes(16)));
break;
case 2:
if (iBlock>0)
serverObj.banManager.BanNickLogin(new Guid(br.ReadBytes(16)),iBlock);
else
serverObj.banManager.AllowNickLogin(new Guid(br.ReadBytes(16)));
break;
}
}
#endregion
#region if (command==Commands.BanManagerGetList) Vraci kdo vsechno je zablokovany
if (command==Commands.BanManagerGetList)
{
CommandSender ret=new CommandSender(socket,Commands.ResponseBanManagerGetList,200);
serverObj.banManager.Save(ret);
ret.SendCommand();
}
#endregion
#region if (command==Commands.BoldAdminCommand) Darovat nebo sebrat nekomu Bold admina
if (command==Commands.BoldAdminCommand)
{
/*BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
byte action=br.ReadByte();
int roomId=br.ReadInt32();
Guid to=new Guid(br.ReadBytes(16)),
fromId=new Guid(br.ReadBytes(16));
RoomInfo room=GetRoom(roomId);
UserInfo user=(UserInfo)room.Users[to];
UserInfo from=(UserInfo)room.Users[fromId];
if (user.IsHost&&action!=1) // hosti maj smulu
{
room.Messages.Add(new SysMessage(fromId,
serverObj.langManager.GetText(room.Language,"system-name"),
serverObj.langManager.GetText(room.Language,"cannot-give-bold-to-host")),true);
}
else if (action==2) // predat prava
{
from.BoldAdminRoom=-1;
user.BoldAdminRoom=roomId;
room.Messages.Add(new SysMessage(Guid.Empty,serverObj.langManager.GetText
(room.Language,"system-name"),string.Format(serverObj.langManager.GetText(room.Language,
user.IsMale?"giveto-m-boldadmin":"giveto-f-boldadmin"),user.Name),
new SysMessage.CmdSetBoldAdmin(to)),true);
}
else if (action==1) // sebrat prava
{
user.BoldAdminRoom=-1;
room.Messages.Add(new SysMessage(Guid.Empty,serverObj.langManager.GetText
(room.Language,"system-name"),string.Format(serverObj.langManager.GetText(room.Language,
user.IsMale?"take-m-boldadmin":"take-f-boldadmin"),user.Name),
new SysMessage.CmdTakeBoldAdmin(to)),true);
}
else if (action==0) // dat prava
{
user.BoldAdminRoom=roomId;
room.Messages.Add(new SysMessage(Guid.Empty,serverObj.langManager.GetText
(room.Language,"system-name"),string.Format(serverObj.langManager.GetText(room.Language,
user.IsMale?"give-m-boldadmin":"give-f-boldadmin"),user.Name),
new SysMessage.CmdSetBoldAdmin(to)),true);
}*/
}
#endregion
#region if (command==Commands.GetUserIP) Zjistit Ip adresu uzivatele
/*
if (command==Commands.GetUserIP)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
Guid usr=new Guid(br.ReadBytes(16));
UserInfo user=(UserInfo)serverObj.usersList[usr];
CommandSender ret=new CommandSender(socket,
Commands.ResponseGetUserIP,30);
// zapsat data
if (user==null)
ret.Write("N/A");
else
ret.Write(user.HostAddress);
ret.SendCommand();
}
*/
#endregion
// posilani zprav atd..
#region if (command==Commands.SendRoomMessage) Poslat zpravu (septani/normalni)
if (command==Commands.SendRoomMessage)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
bool bLocked=br.ReadBoolean();
Guid from=new Guid(br.ReadBytes(16));
Guid to=new Guid(br.ReadBytes(16));
string msg=br.ReadString();
RoomInfo room=GetRoom(roomId);
UserInfo userInfo=(UserInfo)room.Users[from];
#if LOG
WriteLog("Zprava:{0} Od:{1}",msg,userInfo==null?"(null)":userInfo.Name);
#endif
if (userInfo!=null)
{
if (to==Guid.Empty)
{
room.ProcessMessage(serverObj.adSystem,msg);
room.Messages.Add(new NormalMessage(userInfo,msg),true);
}
else
{
UserInfo toUser=(UserInfo)room.Users[to];
if (toUser!=null)
room.Messages.Add(new WhisperMessage(userInfo,toUser,bLocked,msg),true);
}
}
}
#endregion
#region if (command==Commands.SendRoomSysMessage) Poslat zpravu (systemovou)
if (command==Commands.SendRoomSysMessage)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
Guid to=new Guid(br.ReadBytes(16));
string msg=br.ReadString();
int count=br.ReadInt32();
bool translateParams=count<0;
string[] param=new string[count<0?(-count):count];
RoomInfo room=GetRoom(roomId);
// nacist parametry
for(int i=0; i<param.Length; i++)
{
string str=br.ReadString();
if (str==""||str==null)
param[i]="";
else if (translateParams)
param[i]=serverObj.langManager.GetText(room.Language,str);
else
param[i]=str;
}
room.Messages.Add(new SysMessage(to,
serverObj.langManager.GetText(room.Language,"system-name"),
param.Length==0?
serverObj.langManager.GetText(room.Language,msg)
:
string.Format(serverObj.langManager.GetText(room.Language,msg),param)),true);
}
#endregion
#region if (command==Commands.GetRoomMessages) Vratit zpravy v mistnosti (novejsi nez ..xxx..)
if (command==Commands.GetRoomMessages)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
Int64 lastId=br.ReadInt64();
// zjistit mistnost a data ktera se maji poslat
RoomInfo room=GetRoom(roomId);
MessagesListEnumerator msgenum=room.Messages.GetMessages(lastId);
// odpoved + spocitat velikost (jen priblizne)
CommandSender ret=new CommandSender(socket,
Commands.ResponseGetRoomMessages,4+msgenum.MessagesLeft*30);
// zapsat data
ret.Write(msgenum.MessagesLeft);
while(msgenum.MoveNext())
msgenum.CurrentMessage.SaveMessage(ret);
ret.SendCommand();
}
#endregion
// VIP zpravy
#region if (command==Commands.VipSendQuestionToVip) Poslat otazky od moderatora VIPum
if (command==Commands.VipSendQuestionToVip)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
Int64 msgId=br.ReadInt64();
RoomInfo room=GetRoom(roomId);
VipChat chat=room.CurrentVipChat;
int vipCount=br.ReadInt32();
ChatMessage cmsg=chat.GetMessage(msgId);
for(int i=0; i<vipCount; i++)
{
Guid id=new Guid(br.ReadBytes(16));
if (cmsg is NormalMessage)
{
NormalMessage msg=(NormalMessage)cmsg;
chat.AddVipQuestion(new VipQuestion(id,msg.Message,msg.From));
}
else if (cmsg is WhisperMessage)
{
WhisperMessage msg=(WhisperMessage)cmsg;
chat.AddVipQuestion(new VipQuestion(id,msg.Message,msg.FromName));
}
}
}
#endregion
#region if (command==Commands.VipSendMessage) Poslat otazku s odpovedi do mistnosti
if (command==Commands.VipSendMessage)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
string qFrom=br.ReadString(),qText=br.ReadString(),
aFrom=br.ReadString(),aText=br.ReadString(),
aFont=br.ReadString();
RoomInfo room=GetRoom(roomId);
VipMessage vipMsg=new VipMessage(qFrom,qText,aFrom,aText,aFont);
room.CurrentVipChat.AddAnswer(vipMsg);
room.Messages.Add(vipMsg,true);
}
#endregion
#region if (command==Commands.VipGetQuestions) Vip chce otazky - poslat mu je
if (command==Commands.VipGetQuestions)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
Guid vipId=new Guid(br.ReadBytes(16));
RoomInfo room=GetRoom(roomId);
CommandSender ret;
if (room.CurrentVipChat==null)
{
ret=new CommandSender(socket,Commands.ResponseVipGetQuestions,4);
ret.Write(0);
}
else
{
ArrayList questions=room.CurrentVipChat.GetQuestionsFor(vipId);
ret=new CommandSender(socket,Commands.ResponseVipGetQuestions,300*questions.Count);
ret.Write(questions.Count);
foreach(VipQuestion vq in questions)
vq.Save(ret);
}
ret.SendCommand();
}
#endregion
#region if (command==Commands.VipChatStart) Spustit VIP pokec
if (command==Commands.VipChatStart)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
int vipChatId=br.ReadInt32();
RoomInfo room=GetRoom(roomId);
SqlDataReader reader=Database.VipChats.SelectChat(vipChatId);
room.CurrentVipChat=new VipChat(vipChatId,reader,room.Users.Count,room.ID);
serverObj.vipChatsList.Add(room.CurrentVipChat);
}
#endregion
#region if (command==Commands.VipChatEnd) Ukoncit VIP pokec
if (command==Commands.VipChatEnd)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
int roomId=br.ReadInt32();
RoomInfo room=GetRoom(roomId);
VipChat chat=room.CurrentVipChat;
room.CurrentVipChat=null;
serverObj.vipChatsList.Remove(chat);
serverObj.lastVipChat=chat;
}
#endregion
#region if (command==Commands.VipChatAfterEndCmd) Po ukonceni VIP pokecu - umozni ulozit logy atak
if (command==Commands.VipChatAfterEndCmd)
{
BinaryReader br=new BinaryReader(new MemoryStream(dataBuffer));
bool bSaveFull=br.ReadBoolean();
bool bSaveVip=br.ReadBoolean();
if (bSaveFull)
{
serverObj.lastVipChat.SaveMessages(Settings.ConnectionString);
}
StringBuilder sb;
if (bSaveVip)
{
sb=new StringBuilder(4096);
XmlTextWriter wr=new XmlTextWriter(new StringWriter(sb));
serverObj.lastVipChat.SaveDocument(wr);
wr.Close();
//Console.WriteLine(sb.ToString());
}
else
sb=new StringBuilder("");
Database.VipChats.CloseVipChat(serverObj.lastVipChat.ID,sb.ToString(),serverObj.lastVipChat.UsersCount);
serverObj.lastVipChat=null;
}
#endregion
#region if (command==Commands.VipGetCurrentChat) Poslat informace o probihajicich chatech
if (command==Commands.VipGetCurrentChat)
{
CommandSender ret;
ret=new CommandSender(socket,Commands.ResponseVipGetCurrentChat,512);
ret.Write(serverObj.vipChatsList.Count);
foreach(VipChat chat in serverObj.vipChatsList)
{
ret.Write(chat.RoomId);
ret.Write(chat.Name);
ret.Write(chat.Category);
ret.Write(chat.Description);
}
ret.SendCommand();
}
#endregion
}
catch(Exception e)
{
#region Catch exceptions
#if LOG
WriteLog("Oops! Command:{0}\nException:\n{1}",command,e.ToString());
#endif
serverObj.eventLog.WriteEntry(string.Format("Unhandled exception in ProcessCommand\nCommand={0}\n\n{1}",
command.ToString(),e.ToString()));
#endregion
}
// Hotovo .. prijmout dalsi pozadavky
cmdReceived=0;
SetupReceiveCommand();
}
#endregion
#region DEBUG - Logging
#if LOG
private static ArrayList log=null;
private static string path="",path2="";
private static void WriteLog(string format,params object[] param)
{
string s=string.Format(format,param);
if (log==null) log=new ArrayList(50);
log.Add(string.Format("[{0}] {1}",DateTime.Now,s));
Console.WriteLine(s);
if (log.Count==10)
{
if (path=="")
{
path=System.Reflection.Assembly.GetExecutingAssembly().Location;
path=path.Substring(0,path.LastIndexOf('\\'));
path2=path+"\\log2.txt";
path+="\\log.txt";
}
StreamWriter sw;
if (!File.Exists(path))
sw=new StreamWriter(File.Create(path));
else
sw=new StreamWriter(File.OpenWrite(path));
if (sw.BaseStream.Length>1024*1024)
{
sw.Close();
File.Delete(path2);
File.Move(path,path2);
sw=new StreamWriter(File.Create(path));
}
sw.BaseStream.Seek(0,SeekOrigin.End);
foreach(string str in log)
sw.WriteLine(str);
sw.Close();
log.Clear();
}
}
#endif
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment