using System;
using System.Collections.Generic;
using Woodpecker.Core;
using Woodpecker.Specialized.Text;
using Woodpecker.Specialized.Encoding;
using Woodpecker.Game.Rooms.Instances;
using Woodpecker.Game.Rooms.Instances.Interaction;
namespace Woodpecker.Game.Rooms
{
///
/// Contains target methods regarding actions in the Navigator, such as viewing room lists, creating and modifying rooms and authenticating and entering rooms.
///
public class navigatorReactor : Reactor
{
#region Get user flats
///
/// 16 - "@P"
///
public void SUSERF()
{
roomInformation[] Rooms = ObjectTree.Game.Rooms.getFlatsForUser(Session.User);
if (Rooms.Length > 0) // Rooms found!
{
Response.Initialize(16); // "@P"
foreach (roomInformation Room in Rooms)
{
Response.Append(Room.ToUserFlatString());
}
}
else
{
Response.Initialize(57); // "@y"
Response.Append(Session.User.Username);
}
sendResponse();
}
///
/// 17 - "@Q"
///
public void SRCHF()
{
string Criteria = Request.Content.Split('%')[1]; // Get plain criteria
roomInformation[] Rooms = ObjectTree.Game.Rooms.getUserFlatsSearchResult(Criteria);
if (Rooms.Length > 0) // Rooms found!
{
Response.Initialize(55); // "@w"
foreach (roomInformation Room in Rooms)
{
roomCategoryInformation pCategory = ObjectTree.Game.Rooms.getRoomCategory(Room.categoryID);
if (pCategory != null && pCategory.userRoleHasAccess(Session.User.Role))
{
if(!(Room.showOwner
|| Room.ownerID == Session.User.ID
|| Session.User.hasFuseRight("fuse_see_all_roomowners")))
Room.Owner = "-"; // Can't see owner name
Response.Append(Room.ToUserFlatString());
}
}
}
else
Response.Initialize(58); // "@z"
sendResponse();
}
#endregion
#region Favorite room list
///
/// 18 - "@R"
///
public void GETFVRF()
{
Response.Initialize(61); // "@}"
Response.Append("H" + "H" + "J" + Convert.ToChar(2) + "HHH"); // Blegh, messy, but it's static as hedgehogs
Response.Append(ObjectTree.Game.Rooms.getFavoriteRooms(Session.User));
sendResponse();
}
///
/// 19 - "@S"
///
public void ADD_FAVORITE_ROOM()
{
if (ObjectTree.Game.Rooms.getFavoriteRoomCount(Session.User.ID) < Configuration.getNumericConfigurationValue("users.favoriterooms.max"))
{
int[] Parameters = Request.getWiredParameters();
int roomID = Parameters[1];
roomInformation Room = ObjectTree.Game.Rooms.getRoomInformation(roomID);
if (Room != null && ObjectTree.Game.Rooms.getRoomCategory(Room.categoryID).userRoleHasAccess(Session.User.Role)) // Room exist and user has access to room
ObjectTree.Game.Rooms.addFavoriteRoom(Session.User.ID, roomID);
}
else
Session.gameConnection.sendLocalizedError("nav_error_toomanyfavrooms");
}
///
/// 20 - "@T"
///
public void DEL_FAVORITE_ROOM()
{
int[] Parameters = Request.getWiredParameters();
int roomID = Parameters[1];
ObjectTree.Game.Rooms.removeFavoriteRoom(Session.User.ID, roomID);
}
#endregion
#region Flat create and edit
///
/// 21 - "@U"
///
public void GETFLATINFO()
{
int roomID = int.Parse(Request.Content);
roomInformation Room = ObjectTree.Game.Rooms.getRoomInformation(roomID);
if (Room == null || !Room.isUserFlat) // Room is not found / not valid
return;
Response.Initialize(54); // "@v"
Response.appendWired(Room.superUsers);
Response.appendWired((int)Room.accessType);
Response.appendWired(roomID);
if (Room.showOwner || Room.ownerID == Session.User.ID || Session.User.hasFuseRight("fuse_see_all_roomowners"))
Response.appendClosedValue(Room.Owner);
else
Response.appendClosedValue("-");
Response.appendClosedValue(Room.modelType);
Response.appendClosedValue(Room.Name);
Response.appendClosedValue(Room.Description);
roomCategoryInformation Category = ObjectTree.Game.Rooms.getRoomCategory(Room.categoryID);
Response.appendWired(Room.showOwner);
Response.appendWired(Category != null && Category.allowTrading);
Response.appendWired(Room.currentVisitors);
Response.appendWired(Room.maxVisitors);
sendResponse();
}
///
/// 23 - "@W"
///
public void DELETEFLAT()
{
int roomID = int.Parse(Request.Content);
if (ObjectTree.Game.Rooms.userOwnsRoom(Session.User.ID, roomID))
{
ObjectTree.Game.Rooms.deleteFlat(roomID);
ObjectTree.Game.Rooms.destroyRoomInstance(roomID);
}
}
///
/// 24 - "@X"
///
public void UPDATEFLAT()
{
string[] Details = Request.Content.Split('/');
int roomID = int.Parse(Details[0]);
roomInformation Room = ObjectTree.Game.Rooms.getRoomInformation(roomID);
if (Room != null && Room.ownerID == Session.User.ID)
{
stringFunctions.filterVulnerableStuff(ref Details[1], true);
Room.Name = Details[1];
Room.accessType = (roomAccessType)Enum.Parse(typeof(roomAccessType), Details[2]);
Room.showOwner = (Details[3] == "1");
Room.updateSettings();
}
}
///
/// 25 - "@Y"
///
public void SETFLATINFO()
{
int roomID = 0;
if (Request.Content[0] == '/') // Create room
roomID = int.Parse(Request.Content.Split('/')[1]);
else
roomID = int.Parse(Request.Content.Split('/')[0]);
roomInformation Room = ObjectTree.Game.Rooms.getRoomInformation(roomID);
if (Room != null && Room.ownerID == Session.User.ID) // Allowed to edit!
{
string[] Settings = Request.Content.Split(Convert.ToChar(13));
for (int i = 1; i < Settings.Length; i++)
{
int keyLength = Settings[i].IndexOf('=');
string Key = Settings[i].Substring(0, keyLength);
string Value = Settings[i].Substring(keyLength + 1);
switch (Key)
{
case "description":
{
stringFunctions.filterVulnerableStuff(ref Value, true);
Room.Description = Value;
}
break;
case "allsuperuser":
{
Room.superUsers = (Value == "1");
}
break;
case "maxvisitors":
{
Room.maxVisitors = int.Parse(Value);
if (Room.maxVisitors < 10 || Room.maxVisitors > 50)
Room.maxVisitors = 25;
}
break;
case "password":
{
stringFunctions.filterVulnerableStuff(ref Value, false);
Room.Password = Value;
}
break;
default: // Hax
return;
}
}
Room.updateSettings();
}
}
///
/// 29 - "@]"
///
public void CREATEFLAT()
{
if (ObjectTree.Game.Rooms.getUserRoomCount(Session.User.ID) >= Configuration.getNumericConfigurationValue("users.rooms.maxroomsperuser"))
{
Session.gameConnection.sendLocalizedError("Error creating a private room");
return;
}
Response.Initialize(59); // "@{"
string[] Settings = Request.Content.Split('/');
roomInformation newRoom = new roomInformation();
newRoom.ownerID = Session.User.ID;
newRoom.Name = Settings[2];
newRoom.modelType = Settings[3];
stringFunctions.filterVulnerableStuff(ref newRoom.Name, true);
// Verify room model
roomModel testModel = ObjectTree.Game.Rooms.getModel(newRoom.modelType);
if (testModel == null
|| testModel.userType == roomModelUserType.PublicSpaceModel
|| testModel.userType == roomModelUserType.UserFlatSpecialModel && !Session.User.hasFuseRight("fuse_use_special_room_layouts"))
return; // Model does not exist, model is for public spaces only or model requires certain FUSE right and user does not has this fuse right
newRoom.accessType = (roomAccessType)Enum.Parse(typeof(roomAccessType), Settings[4]);
newRoom.showOwner = (Settings[5] == "1");
int newRoomID = ObjectTree.Game.Rooms.createFlat(newRoom);
Response.Append(newRoomID);
Response.appendChar(13);
Response.Append(newRoom.Name);
sendResponse();
}
#endregion
#region Navigator categories
///
/// 150 - "BV"
///
public void NAVIGATE()
{
int categoryID = Request.getWiredParameters()[1];
Response.Initialize(220); // "C\"
roomCategoryInformation pCategory = ObjectTree.Game.Rooms.getRoomCategory(categoryID);
if (pCategory != null && pCategory.userRoleHasAccess(Session.User.Role)) // Valid category
{
bool hideFull = wireEncoding.decodeBoolean(Request.Content.Substring(0, 1));
#region Build category info
Response.appendWired(hideFull);
Response.appendWired(pCategory.ID);
if (pCategory.forPublicSpaces)
Response.appendWired(false); // Public spaces
else
Response.appendWired(2); // User flats
Response.appendClosedValue(pCategory.Name);
Response.appendWired(pCategory.currentVisitors);
Response.appendWired(pCategory.maxVisitors);
Response.appendWired(pCategory.parentID);
List Rooms = ObjectTree.Game.Rooms.getCategoryRooms(categoryID, !pCategory.forPublicSpaces);
if (!pCategory.forPublicSpaces) // User flats
Response.appendWired(Rooms.Count);
#endregion
#region Build rooms info
foreach (roomInformation lRoom in Rooms)
{
if (!hideFull || lRoom.currentVisitors <= lRoom.maxVisitors)
Response.Append(lRoom.ToString(Session.User));
}
#endregion
#region Build subcategory info
foreach (roomCategoryInformation lSubcategory in ObjectTree.Game.Rooms.getChildRoomCategories(pCategory.ID))
{
if (lSubcategory.userRoleHasAccess(Session.User.Role) && (!hideFull || lSubcategory.currentVisitors < lSubcategory.maxVisitors)) // User has access to this room category and requests to see this category
{
Response.appendWired(lSubcategory.ID);
Response.appendWired(false);
Response.appendClosedValue(lSubcategory.Name);
Response.appendWired(lSubcategory.currentVisitors);
Response.appendWired(lSubcategory.maxVisitors);
Response.appendWired(pCategory.ID);
}
}
#endregion
}
sendResponse();
}
///
/// 151 - "BW"
///
public void GETUSERFLATCATS()
{
Response.Initialize(221); // "C]"
List Categories = ObjectTree.Game.Rooms.getAvailableFlatCategories(Session.User.Role);
Response.appendWired(Categories.Count);
foreach (roomCategoryInformation lCategory in Categories)
{
Response.appendWired(lCategory.ID);
Response.appendClosedValue(lCategory.Name);
}
sendResponse();
}
///
/// 152 - "BX"
///
public void GETFLATCAT()
{
int roomID = Request.getNextWiredParameter();
roomInformation Room = ObjectTree.Game.Rooms.getRoomInformation(roomID);
Response.Initialize(222); // "C^"
if (Room != null)
{
Response.appendWired(Room.ID);
Response.appendWired(Room.categoryID);
}
sendResponse();
}
///
/// 153 - "BY"
///
public void SETFLATCAT()
{
int[] Parameters = Request.getWiredParameters();
int roomID = Parameters[0];
int categoryID = Parameters[1];
roomCategoryInformation newCategory = ObjectTree.Game.Rooms.getRoomCategory(categoryID);
if (newCategory != null && newCategory.userRoleCanPutFlat(Session.User.Role)) // Valid category
{
roomInformation Room = ObjectTree.Game.Rooms.getRoomInformation(roomID);
if (Room != null && Room.ownerID == Session.User.ID && Room.categoryID != newCategory.ID) // Valid change
{
Room.categoryID = newCategory.ID;
Room.updateSettings();
if (ObjectTree.Game.Rooms.roomInstanceRunning(roomID))
ObjectTree.Game.Rooms.getRoomInstance(roomID).Information = Room;
}
}
}
#endregion
#region Enter room
#region Target methods
///
/// 2 - "@B"
///
public void ROOM_DIRECTORY()
{
if (Session.inRoom)
Session.leaveRoom(true);
bool publicSpace = (Request.Content[0] == 'A'); // Base64 A = 1, @ = 0
int roomID = wireEncoding.Decode(Request.Content.Substring(1));
Response.Initialize(19); // "@S"
sendResponse();
if (publicSpace)// No flat checks
{
roomInstance pInstance = ObjectTree.Game.Rooms.getRoomInstance(roomID);
if(pInstance != null && !pInstance.Information.isUserFlat)
goToRoom(roomID);
}
}
///
/// 53 - "@u"
///
public void QUIT()
{
Session.leaveRoom(true);
}
///
/// 54 - "@v"
///
public void GOVIADOOR()
{
string[] Data = Request.Content.Split('/');
int roomID = int.Parse(Data[0]);
int itemID = int.Parse(Data[1]);
if(Session.authenticatedFlat == roomID && Session.authenticatedTeleporter == itemID) // Authenticated for flat and teleporter item
{
roomInstance pInstance = ObjectTree.Game.Rooms.getRoomInstance(roomID);
if(pInstance != null)
{
pInstance.registerSession(Session.ID);
Response.Initialize(19); // "@S"
sendResponse();
}
}
}
///
/// 57 - "@y"
///
public void TRYFLAT()
{
int roomID = 0;
string givenPassword = null;
if (Request.Content.Contains("/"))
{
string[] Details = Request.Content.Split('/');
roomID = int.Parse(Details[0]);
givenPassword = Details[1];
}
else
roomID = int.Parse(Request.Content);
roomInformation Room = ObjectTree.Game.Rooms.getRoomInformation(roomID);
if (Room == null)
return;
if (Session.authenticatedTeleporter > 0)
{
if (roomID != Session.authenticatedFlat)
return; // Attempting to enter different flat via authenticated teleporter
}
else
{
if (Room.accessType != roomAccessType.open && Room.ownerID != Session.User.ID && !Session.User.hasFuseRight("fuse_enter_locked_rooms")) // Can't override checks
{
if (Room.accessType == roomAccessType.password) // Passworded room
{
if (givenPassword != Room.Password) // Incorrect password given
{
Session.gameConnection.sendLocalizedError("Incorrect flat password");
return;
}
}
else // Doorbell
{
int messageID = 131; // "BC" (no answer)
if (ObjectTree.Game.Rooms.roomInstanceRunning(roomID))
{
roomInstance Instance = ObjectTree.Game.Rooms.getRoomInstance(roomID);
if (Instance.castDoorbellUser(Session.User.Username))
{
messageID = 91; // "A["
Instance.registerSession(Session.ID);
Session.waitingFlat = roomID;
}
}
Response.Initialize(messageID);
sendResponse();
return; // Wait for the eventual response
}
}
Session.authenticatedFlat = roomID;
}
Response.Initialize(41); // "@i"
sendResponse();
}
///
/// 59 - "@{"
///
public void GOTOFLAT()
{
int roomID = int.Parse(Request.Content);
if (roomID == Session.authenticatedFlat) // User has authenticated at TRYFLAT (message 57) and is trying to enter the room he/she authenticated for
goToRoom(roomID);
}
///
/// 88 - "AX"
///
public void STOP()
{
/* Putting this target method in the roomReactor will not work, put it here instead */
if (Session.inRoom)
{
string Status = Request.Content;
if (Status == "CarryItem")
Session.roomInstance.getRoomUser(Session.ID).removeStatus("handitem");
else if (Status == "Dance")
Session.roomInstance.getRoomUser(Session.ID).removeStatus("dance");
}
}
///
/// 154 - "BZ"
///
public void GETSPACENODEUSERS()
{
Response.Initialize(223); // "C_"
int roomID = Request.getNextWiredParameter();
if (ObjectTree.Game.Rooms.roomInstanceRunning(roomID))
Response.Append(ObjectTree.Game.Rooms.getRoomInstance(roomID).getUserList());
sendResponse();
}
///
/// 182 - "Bv"
///
public void GETINTERST()
{
Response.Initialize(258); // "DB"
string adImage = ""; // TODO: configure this interstitial ad
string adUri = ""; // TODO: idem dito
if (adImage.Length > 0)
{
Response.appendTabbedValue(adImage);
Response.Append(adUri);
}
else
Response.Append(0); // No advertisement to be shown
sendResponse();
}
#endregion
#region Methods
///
/// Tries to add this user to the room instance with a given ID.
///
/// The database ID of the room to try to enter.
private void goToRoom(int roomID)
{
try
{
roomInstance Instance = ObjectTree.Game.Rooms.getRoomInstance(roomID);
if (Instance.Information == null || !Instance.userRoleHasAccess(Session.User.Role)) // Instance not OK for user
return;
if (Instance.isFull) // Room is full
{
if (!Session.User.hasFuseRight("fuse_enter_full_rooms") && Session.User.ID != Instance.Information.ownerID) // User has no FUSE right to enter full rooms and user is not the room owner
{
Response.Initialize(224); // "C`"
Response.appendWired(1); // 'User flat full'
sendResponse();
return;
}
}
Instance.registerSession(this.Session.ID);
Session.roomInstance = Instance;
Response.Initialize(166); // "Bf"
Response.Append("interstitial advertisement goes here");
sendResponse();
Response.Initialize(69); // "AE"
Response.Append(Instance.Information.modelType);
Response.Append(" ");
Response.Append(Instance.roomID);
sendResponse();
if (Instance.Information.isUserFlat)
{
Response.Initialize(46); // "@n"
Response.Append("wallpaper/");
Response.Append(Instance.Information.Wallpaper);
sendResponse();
Response.Initialize(46); // "@n"
Response.Append("floor/");
Response.Append(Instance.Information.Floor);
sendResponse();
Session.gameConnection.reactorHandler.Register(new flatReactor());
}
else
Session.gameConnection.reactorHandler.Register(new roomReactor());
}
catch { }
}
#endregion
#endregion
#region Other
///
/// "B[" - "REMOVEALLRIGHTS"
///
public void Listener155()
{
int roomID = Request.getNextWiredParameter();
if (ObjectTree.Game.Rooms.userOwnsRoom(Session.User.ID, roomID))
ObjectTree.Game.Rooms.removeRoomRights(roomID);
}
#endregion
}
}