Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Unite

Status
Not open for further replies.
Joined
Apr 27, 2008
Messages
446
Reaction score
168
Unite

Features:

  • Caching
  • Security
  • Free licensing
  • From scratch

Snippets:
Code:
using System.Collections.Generic;using Unite.HabboHotel.Friendlist;
using Unite.HabboHotel.GameClients;
using Unite.HabboHotel.Users;
using Unite.HabboHotel.Users.Friendlist;
using Unite.Messages;


namespace Unite.Communication.Messages.Outgoing
{
    internal class FriendlistComponents
    {
        public static void FriendCategoryData(ServerMessage serverMessage, FriendCategory friendCategory)
        {
            serverMessage.AppendInt(friendCategory.CategoryId);
            serverMessage.AppendString(friendCategory.Name);
        }


        public static void FriendData(ServerMessage serverMessage, Friendship friendship)
        {
            User user = Unite.GetGame().UserManager.GetUser(friendship.FriendId);


            serverMessage.AppendInt(user.Id);
            serverMessage.AppendString(user.Name);
            serverMessage.AppendInt(user.Gender == "M" ? 1 : 0);
            serverMessage.AppendBoolean(user.Online);
            serverMessage.AppendBoolean(user.FollowingAllowed);
            serverMessage.AppendString(user.Figure);
            serverMessage.AppendInt(friendship.CategoryId);
            serverMessage.AppendString(user.Motto);
            serverMessage.AppendString(user.LastAccess);
            serverMessage.AppendString(user.RealName);
            serverMessage.AppendBoolean(false); //PersistedMessageUser
            serverMessage.AppendBoolean(false); //VipMember
            serverMessage.AppendBoolean(false); //PocketHabboUser
            serverMessage.AppendShort(0); //RelationshipStatus
        }


        public static void HabboSearchResultData(ServerMessage serverMessage, int userId)
        {
            User user = Unite.GetGame().UserManager.GetUser(userId);


            serverMessage.AppendInt(user.Id);
            serverMessage.AppendString(user.Name);
            serverMessage.AppendString(user.Motto);
            serverMessage.AppendBoolean(user.Online);
            serverMessage.AppendBoolean(user.FollowingAllowed);
            serverMessage.AppendString(user.LastAccess);
            serverMessage.AppendInt(user.Gender == "M" ? 1 : 0);
            serverMessage.AppendString(user.Figure);
            serverMessage.AppendString(user.RealName);
        }


        public static void FriendRequest(ServerMessage serverMessage, FriendRequest friendRequest)
        {
            User user = Unite.GetGame().UserManager.GetUser(friendRequest.UserId);


            serverMessage.AppendInt(friendRequest.UserId);
            serverMessage.AppendString(user.Name);
            serverMessage.AppendString(user.Figure);
        }


        public static void AcceptFriendFailureData(ServerMessage serverMessage, AcceptFriendFailure acceptFriendFailure)
        {
            serverMessage.AppendInt(acceptFriendFailure.SenderId);
            serverMessage.AppendInt(acceptFriendFailure.ErrorCode);
        }
    }


    internal class FriendlistComposers
    {
        public static void MessengerInitMessageComposer(GameClient gameClient, List<FriendCategory> friendCategories, List<Friendship> friendships)
        {
            var serverMessage = new ServerMessage(1603);


            serverMessage.AppendInt(100); //_userFriendLimit
            serverMessage.AppendInt(100); //_normalFriendLimit
            serverMessage.AppendInt(100); //_extendedFriendLimit
            serverMessage.AppendInt(100); //_evenMoreExtendedFriendLimit


            serverMessage.AppendInt(friendCategories.Count);
            foreach (FriendCategory friendCategory in friendCategories)
            {
                FriendlistComponents.FriendCategoryData(serverMessage, friendCategory);
            }


            serverMessage.AppendInt(friendships.Count);
            foreach (Friendship friendship in friendships)
            {
                FriendlistComponents.FriendData(serverMessage, friendship);
            }


            gameClient.SendMessage(serverMessage);
        }


        public static void FriendRequestsMessageComposer(GameClient gameClient, List<FriendRequest> friendRequests)
        {
            var serverMessage = new ServerMessage(2313);


            serverMessage.AppendInt(friendRequests.Count);
            serverMessage.AppendInt(friendRequests.Count);


            foreach (FriendRequest messengerRequest in friendRequests)
            {
                FriendlistComponents.FriendRequest(serverMessage, messengerRequest);
            }


            gameClient.SendMessage(serverMessage);
        }


        public static void AcceptFriendResultMessageComposer(GameClient gameClient, List<AcceptFriendFailure> failures)
        {
            var serverMessage = new ServerMessage(1859);


            serverMessage.AppendInt(failures.Count);
            foreach (var failure in failures)
            {
                FriendlistComponents.AcceptFriendFailureData(serverMessage, failure);
            }


            gameClient.SendMessage(serverMessage);
        }


        public static void FindFriendsProcessResultMessageComposer(GameClient gameClient, bool success)
        {
            var serverMessage = new ServerMessage(3955);


            serverMessage.AppendBoolean(success);


            gameClient.SendMessage(serverMessage);
        }


        public static void FollowFriendFailedMessageComposer(GameClient gameClient, int errorCode)
        {
            var serverMessage = new ServerMessage(621);


            serverMessage.AppendInt(errorCode);


            gameClient.SendMessage(serverMessage);
        }


        public static void FriendListUpdateMessageComposer(GameClient gameClient,
            List<FriendCategory> updateCategories,
            List<int> removedFriendIds, Dictionary<Friendship, int> updatedFriends)
        {
            var serverMessage = new ServerMessage(596);


            serverMessage.AppendInt(updateCategories.Count);
            foreach (var messengerCategory in updateCategories)
            {
                FriendlistComponents.FriendCategoryData(serverMessage, messengerCategory);
            }


            serverMessage.AppendInt(updatedFriends.Count + removedFriendIds.Count);


            foreach (var buddy in removedFriendIds)
            {
                serverMessage.AppendInt(-1);
                serverMessage.AppendInt(buddy);
            }


            foreach (var buddyUpdate in updatedFriends)
            {
                serverMessage.AppendInt(buddyUpdate.Value);
                FriendlistComponents.FriendData(serverMessage, buddyUpdate.Key);
            }


            gameClient.SendMessage(serverMessage);
        }


        public static void FriendNotificationMessageComposer(GameClient gameClient,
            FriendNotification friendNotification)
        {
            var serverMessage = new ServerMessage(2005);


            serverMessage.AppendInt(friendNotification.TypeCode);
            serverMessage.AppendString(friendNotification.AvatarId);
            serverMessage.AppendString(friendNotification.Message);


            gameClient.SendMessage(serverMessage);
        }


        public static void HabboSearchResultMessageComposer(GameClient gameClient, List<int> freinds,
            List<int> others)
        {
            var serverMessage = new ServerMessage(390);


            serverMessage.AppendInt(freinds.Count);
            foreach (int messengerBuddy in freinds)
            {
                FriendlistComponents.HabboSearchResultData(serverMessage, messengerBuddy);
            }


            serverMessage.AppendInt(others.Count);
            foreach (int messengerBuddy in others)
            {
                FriendlistComponents.HabboSearchResultData(serverMessage, messengerBuddy);
            }


            gameClient.SendMessage(serverMessage);
        }


        public static void InstantMessageErrorMessageComposer(GameClient gameClient, int errorCode, int userId,
            string message)
        {
            var serverMessage = new ServerMessage(1180);


            serverMessage.AppendInt(errorCode);
            serverMessage.AppendInt(userId);
            serverMessage.AppendString(message);


            gameClient.SendMessage(serverMessage);
        }


        public static void MessengerErrorMessageComposer(GameClient gameClient, int clientMessageId, int errorCode)
        {
            var serverMessage = new ServerMessage(3543);


            serverMessage.AppendInt(clientMessageId);
            serverMessage.AppendInt(errorCode);


            gameClient.SendMessage(serverMessage);
        }


        public static void MiniMailNewMessageMessageComposer(GameClient gameClient)
        {
            var serverMessage = new ServerMessage(113);


            gameClient.SendMessage(serverMessage);
        }


        public static void MiniMailUnreadCountMessageComposer(GameClient gameClient, int unreadMessageCount)
        {
            var serverMessage = new ServerMessage(1822);


            serverMessage.AppendInt(unreadMessageCount);


            gameClient.SendMessage(serverMessage);
        }


        public static void NewConsoleMessageMessageComposer(GameClient gameClient, int senderId, string messageText,
            int secondsSinceSent)
        {
            var serverMessage = new ServerMessage(2393);


            serverMessage.AppendInt(senderId);
            serverMessage.AppendString(messageText);
            serverMessage.AppendInt(secondsSinceSent);


            gameClient.SendMessage(serverMessage);
        }


        public static void NewFriendRequestMessageComposer(GameClient gameClient, FriendRequest friendRequest)
        {
            var serverMessage = new ServerMessage(2279);


            FriendlistComponents.FriendRequest(serverMessage, friendRequest);


            gameClient.SendMessage(serverMessage);
        }


        public static void RoomInviteErrorMessageComposer(GameClient gameClient, int errorCode,
            List<int> failedRecipients)
        {
            var serverMessage = new ServerMessage(1832);


            serverMessage.AppendInt(errorCode);


            serverMessage.AppendInt(failedRecipients.Count);
            foreach (var failedRecipient in failedRecipients)
            {
                serverMessage.AppendInt(failedRecipient);
            }


            gameClient.SendMessage(serverMessage);
        }


        public static void RoomInviteMessageComposer(GameClient gameClient, int senderId, string messageText)
        {
            var serverMessage = new ServerMessage(2557);


            serverMessage.AppendInt(senderId);
            serverMessage.AppendString(messageText);


            gameClient.SendMessage(serverMessage);
        }
    }
}

Code:
using System.Collections.Generic;using System.Data;
using System.Linq;
using Unite.Core;
using Unite.HabboHotel.Catalog.Enum;
using Unite.Storage;


namespace Unite.HabboHotel.Catalog
{
    internal class CatalogManager
    {
        private CatalogNode _rootNodeNormal;
        private CatalogNode _rootNodeBuilder;
        private readonly List<CatalogPage> _catalogPages;
        private readonly List<CatalogProduct> _catalogProducts;


        public CatalogManager()
        {
            _catalogPages = new List<CatalogPage>();
            _catalogProducts = new List<CatalogProduct>();
        }


        public void Initialize(DatabaseClient databaseClient)
        {
            Logging.Write("[CatalogManager] ");


            _catalogPages.Clear();
            _catalogProducts.Clear();


            var catalogProductsDataTable = databaseClient.ReadDataTable("SELECT * FROM catalog_products");
            if (catalogProductsDataTable == null) return;


            foreach (DataRow catalogProductDataRow in catalogProductsDataTable.Rows)
            {
                _catalogProducts.Add(new CatalogProduct((int) catalogProductDataRow["ProductId"],
                    (string) catalogProductDataRow["ProductType"], (int) catalogProductDataRow["FurniClassId"],
                    (string) catalogProductDataRow["ExtraParam"], (int) catalogProductDataRow["ProductCount"],
                    Unite.EnumToBool((string) catalogProductDataRow["UniqueLimitedItem"]),
                    (int) catalogProductDataRow["UniqueLimitedItemSeriesSize"],
                    (int) catalogProductDataRow["UniqueLimitedItemsLeft"]));
            }


            var catalogPagesDataTable = databaseClient.ReadDataTable("SELECT * FROM catalog_pages");
            if (catalogPagesDataTable == null) return;


            foreach (DataRow catalogPageDataRow in catalogPagesDataTable.Rows)
            {
                databaseClient.AddParamWithValue("PageId", (int) catalogPageDataRow["PageId"]);


                var catalogOffersDataTable =
                    databaseClient.ReadDataTable("SELECT * FROM catalog_offers WHERE PageId = [USER=1333342663]Page[/USER]Id");


                _catalogPages.Add(new CatalogPage((int) catalogPageDataRow["PageId"], (int) catalogPageDataRow["Parent"],
                    (string) catalogPageDataRow["PageName"], (string) catalogPageDataRow["Localization"],
                    (int) catalogPageDataRow["Icon"],
                    Unite.EnumToBool((string) catalogPageDataRow["Visible"]),
                    (string) catalogPageDataRow["CatalogType"],
                    (string) catalogPageDataRow["LayoutCode"],
                    ((string) catalogPageDataRow["Images"] == ""
                        ? new List<string>()
                        : ((string) catalogPageDataRow["Images"]).Split('|').ToList()),
                    ((string) catalogPageDataRow["Texts"] == ""
                        ? new List<string>()
                        : ((string) catalogPageDataRow["Texts"]).Split('|').ToList()),
                    (from DataRow catalogOfferDataRow in catalogOffersDataTable.Rows
                        select
                            new CatalogOffer((int) catalogOfferDataRow["OfferId"],
                                (string) catalogOfferDataRow["LocalizationId"],
                                (int) catalogOfferDataRow["PriceInCredits"],
                                (int) catalogOfferDataRow["PriceInActivityPoints"],
                                (int) catalogOfferDataRow["ActivityPointType"], (int) catalogOfferDataRow["ClubLevel"],
                                Unite.EnumToBool((string) catalogOfferDataRow["Rent"]),
                                Unite.EnumToBool((string) catalogOfferDataRow["Giftable"]),
                                Unite.EnumToBool((string) catalogOfferDataRow["BundlePurchaseAllowed"]),
                                (string) catalogOfferDataRow["Products"] == ""
                                    ? new List<CatalogProduct>()
                                    : ((string) catalogOfferDataRow["Products"]).Split(',')
                                        .Select(
                                            productId =>
                                                _catalogProducts.Find(
                                                    product => product.ProductId == int.Parse(productId)))
                                        .ToList())).ToList(), (int) catalogPageDataRow["OfferId"],
                    Unite.EnumToBool((string) catalogPageDataRow["AcceptSeasonCurrencyAsCredits"])));
            }


            _rootNodeNormal = new CatalogNode(CatalogType.Normal);
            _rootNodeBuilder = new CatalogNode(CatalogType.Builder);


            Logging.WriteLine("Initialization done.");
        }


        public CatalogNode GetCatalogNode(string catalogType)
        {
            switch (catalogType)
            {
                case CatalogType.Normal:
                    return _rootNodeNormal;
                case CatalogType.Builder:
                    return _rootNodeBuilder;
                default:
                    return _rootNodeNormal;
            }
        }


        public CatalogPage GetCatalogPage(int pageId)
        {
            return _catalogPages.Find(catalogPage => catalogPage.PageId == pageId);
        }


        public List<CatalogPage> GetCatalogPages(int parent, string catalogType)
        {
            return
                _catalogPages.Where(
                    catalogPage => catalogPage.CatalogType == catalogType && catalogPage.Parent == parent).ToList();
        }


        public List<CatalogPage> GetCatalogPages(int parent)
        {
            return _catalogPages.Where(catalogPage => catalogPage.Parent == parent).ToList();
        }
    }
}
 

AWA

Master Summoner
Loyal Member
Joined
Feb 24, 2008
Messages
595
Reaction score
389
Good naming convention! Bad initializing of CatalogPage and other db objects though..
 
Joined
Aug 10, 2011
Messages
7,399
Reaction score
3,305
Why bad? They are just loaded one time on server loading/reloading.

Pass your Database row or whatever in the constructor.

The bad naming convention he is talking about is probably the underscores. I don't know why somebody started that but its not needed. For properties you can use this.<propertie>

Personal taste but I think properties with underscore just look horrible.
 
Custom Title Activated
Loyal Member
Joined
Oct 26, 2012
Messages
2,357
Reaction score
1,086
Pass your Database row or whatever in the constructor.

The bad naming convention he is talking about is probably the underscores. I don't know why somebody started that but its not needed. For properties you can use this.<propertie>

Personal taste but I think properties with underscore just look horrible.

You mean variables? He's not using properties at all.

OT: You shouldn't start variable names with an underscore, just with a lower-case character (like userName except of _userName or _username), it looks much better. And change the constructor from (int id, string name etc.) to a constructor with only DataRow, you can easily set the variables/properties with the DataRow, it looks much cleaner.

Nonetheless, good luck I suppose. Is this old or new crypto?
 
Joined
Aug 10, 2011
Messages
7,399
Reaction score
3,305
You mean variables? He's not using properties at all.

OT: You shouldn't start variable names with an underscore, just with a lower-case character (like userName except of _userName or _username), it looks much better. And change the constructor from (int id, string name etc.) to a constructor with only DataRow, you can easily set the variables/properties with the DataRow, it looks much cleaner.

Nonetheless, good luck I suppose. Is this old or new crypto?

class properties.

variables/properties with the DataRow

= setting properties of the class from values with the DataRow.

Thanks for copying me Mr. Know All.
 

AWA

Master Summoner
Loyal Member
Joined
Feb 24, 2008
Messages
595
Reaction score
389
Why bad? They are just loaded one time on server loading/reloading.
Yeah, if you think of performance difference, it's nothing. It's just about readability and how it usually is easier to work with when you do it in the constructor instead of the parameters.
 
Retired
Loyal Member
Joined
May 5, 2007
Messages
497
Reaction score
665
Pass your Database row or whatever in the constructor.

The bad naming convention he is talking about is probably the underscores. I don't know why somebody started that but its not needed. For properties you can use this.<propertie>

Personal taste but I think properties with underscore just look horrible.

I totally agree. In fact, the naming convention for C# on MSDN explicitly says that you shall avoid underscores:
:
Do not use underscores, hyphens, or any other nonalphanumeric characters.

When it comes to capitalization, read more about that on this webpage:


And I also agree that sending the DataRow object as a parameter is a better approach. Both maintainability-wise and performance-wise.

Edit:
Also, if it may not be too late yet, one architecture you might wanna take a look at is to have one packet handler per class. So one call would for example be LoginMessageHandler, ChatMessageHandler and so forth where they all inplement an IMessageHandler. Maybe this would get you going? ;)
 
Joined
Apr 27, 2008
Messages
446
Reaction score
168
I totally agree. In fact, the naming convention for C# on MSDN explicitly says that you shall avoid underscores:
:


When it comes to capitalization, read more about that on this webpage:


And I also agree that sending the DataRow object as a parameter is a better approach. Both maintainability-wise and performance-wise.

Edit:
Also, if it may not be too late yet, one architecture you might wanna take a look at is to have one packet handler per class. So one call would for example be LoginMessageHandler, ChatMessageHandler and so forth where they all inplement an IMessageHandler. Maybe this would get you going? ;)

Underlines are used only in db table names.

Sending DataRow as param will make every CatalogPage/CatalogItem load new "using"s.

Any profits from your handlers methods?
 
Joined
Aug 10, 2011
Messages
7,399
Reaction score
3,305
Edit:
Also, if it may not be too late yet, one architecture you might wanna take a look at is to have one packet handler per class. So one call would for example be LoginMessageHandler, ChatMessageHandler and so forth where they all inplement an IMessageHandler. Maybe this would get you going? ;)

This ^

I moved every packet to its own class so easy to instantiate from anywhere in the emulator :D

Sending DataRow as param will make every CatalogPage/CatalogItem load new "using"s.

After no more pointers to the object, it is deleted. Also every DataRow you have is already an object so differenece is not noticable in performance.

Any profits from your handlers methods?

Have a assosiative array that has header => new IMessageHandler(). Pass the header to the list, correct handler gets executed.

- Easy to add new Handlers / maintainable.
- Can be easily invoked from anywhere else in your emulator, not neccessary from a packet.

Suggest you to do the same for Composers (IComposerHandler).
 
Not so spooky...
Loyal Member
Joined
May 22, 2010
Messages
1,017
Reaction score
276
Think you all missed Free licensing witch tell's me a closed source project... nty this will probably end up like The IDK Project... :stupido2: :junglejane:

Anyway good luck.
 
Experienced Elementalist
Joined
Mar 13, 2011
Messages
275
Reaction score
106
I don't understand why do you start a project without tell what do you want to do, I just see four features that doesn't tell me so much and I suppose it's a server for those snippets. It doesn't cost you anything to explain us or show a bit more about the project like everyone else, I just see 2 snippets with any information and I consider it a spam dev.

PD: I don't want to be an idiot but is my point of view to improve and make it nice, not sure if all of you think the same but I find it poor
 
Joined
Apr 27, 2008
Messages
446
Reaction score
168
Think you all missed Free licensing witch tell's me a closed source project... nty this will probably end up like The IDK Project... :stupido2: :junglejane:

Anyway good luck.

Source is on private GitHub's repo, so if somebody really needs it, I guess it won't be a problem.

I don't understand why do you start a project without tell what do you want to do, I just see four features that doesn't tell me so much and I suppose it's a server for those snippets. It doesn't cost you anything to explain us or show a bit more about the project like everyone else, I just see 2 snippets with any information and I consider it a spam dev.

PD: I don't want to be an idiot but is my point of view to improve and make it nice, not sure if all of you think the same but I find it poor
Like what? C#, MySQL, nothing else interesting.
 
Experienced Elementalist
Joined
Mar 13, 2011
Messages
275
Reaction score
106
Source is on private GitHub's repo, so if somebody really needs it, I guess it won't be a problem.


Like what? C#, MySQL, nothing else interesting.

You just tell you are going to make a secure emulator from scratch and you put two snippets, you don't put images, you don't talk anything about the emulator release, features, etc...

Is your project so feel free to do whatever you want, maybe you are a great programmer and your Emulator is nice but if i'm honest this dev reminds me the silly ones made by kids on some other communities like Kekomundo.
 
Joined
Apr 27, 2008
Messages
446
Reaction score
168
You just tell you are going to make a secure emulator from scratch and you put two snippets, you don't put images, you don't talk anything about the emulator release, features, etc...

Is your project so feel free to do whatever you want, maybe you are a great programmer and your Emulator is nice but if i'm honest this dev reminds me the silly ones made by kids on some other communities like Kekomundo.
Made this screen when made thread, but then decided that it actually shows nothing.
ab0QNxB - Unite - RaGEZONE Forums
 

Attachments

You must be registered for see attachments list
Joined
Apr 27, 2008
Messages
446
Reaction score
168
Update time
Catalogue done(deals with badges, credits+activity points, badges, bots, pets(to-check))
Room settings done, only left roomcontrollers and ban stuff
Inventory done(badges, items, pets, bots), no rentables yet
Navigator mostly done
Friendlist was already done

yZv3g6X - Unite - RaGEZONE Forums


Snippets:
Code:
        public void PurchaseFromCatalog(GameClient gameClient, int pageId, int offerId, string extradata, int quantity)
        {
            CatalogPage catalogPage = GetCatalogPage(pageId);
            if (catalogPage == null)
            {
                return;
            }


            CatalogOffer catalogOffer = catalogPage.Offers.FirstOrDefault(offer => offer.OfferId == offerId);
            if (catalogOffer == null)
            {
                return;
            }


            if (catalogOffer.ClubLevel > gameClient.GetUser().ClubLevel)
            {
                CatalogComposers.PurchaseNotAllowedMessageComposer(gameClient, 1);
                return;
            }


            bool notEnoughCredits = catalogOffer.PriceInCredits > gameClient.GetUser().Credits;
            bool notEnoughActivityPoints = catalogOffer.PriceInActivityPoints > gameClient.GetUser().ActivityPoints;
            if (notEnoughCredits || notEnoughActivityPoints)
            {
                CatalogComposers.NotEnoughBalanceMessageComposer(gameClient, notEnoughCredits, notEnoughActivityPoints);
                return;
            }


            gameClient.GetUser().Credits = gameClient.GetUser().Credits - catalogOffer.PriceInCredits;
            gameClient.GetUser().ActivityPoints = gameClient.GetUser().ActivityPoints - catalogOffer.PriceInActivityPoints;
            gameClient.GetUser().UpdateBalance();


            foreach (CatalogProduct catalogProduct in catalogOffer.Products)
            {
                switch (catalogProduct.ProductType)
                {
                    case ProductType.Item:
                        Unite.Game.ItemManager.CreateItem(gameClient.UserId, catalogProduct.FurniClassId, true, catalogProduct.ExtraParam);
                        break;
                    case ProductType.Stuff:
                        Unite.Game.ItemManager.CreateItem(gameClient.UserId, catalogProduct.FurniClassId, false, catalogProduct.ExtraParam);
                        break;
                    case ProductType.Effect:
                        break;
                    case ProductType.Club:
                        break;
                    case ProductType.Badge:
                        Unite.Game.UserManager.CreateBadge(gameClient.UserId, catalogProduct.ExtraParam);
                        break;
                    case ProductType.GameToken:
                        break;
                    case ProductType.Pet:
                        Unite.Game.ItemManager.CreatePet(gameClient.UserId, extradata, false);
                        break;
                    case ProductType.RentableBot:
                        Unite.Game.ItemManager.CreateBot(gameClient.UserId, extradata, false);
                        break;
                }
            }


            CatalogComposers.PurchaseOKMessageComposer(gameClient, catalogOffer);
        }
 

Attachments

You must be registered for see attachments list
Status
Not open for further replies.
Back
Top