private OperationResponse ItemOperationDestroy(Item item, DestroyItem operation)
        {
            MethodReturnValue result = this.CheckAccess(item);

            if (result.IsOk)
            {
                item.Destroy();
                item.Dispose();
                this.RemoveItem(item);

                item.World.ItemCache.RemoveItem(item.Id);
                var eventInstance = new ItemDestroyed {
                    ItemId = item.Id
                };
                var eventData = new EventData((byte)EventCode.ItemDestroyed, eventInstance);
                this.Peer.SendEvent(eventData, new SendParameters {
                    ChannelId = Settings.ItemEventChannel
                });

                // no response, event is sufficient
                operation.OnComplete();
                return(null);
            }

            return(operation.GetOperationResponse(result));
        }
Exemplo n.º 2
0
 public UnturnedItem(Item item, DestroyItem destroyItem)
 {
     m_DestroyItem = destroyItem;
     Item          = item;
     Asset         = new UnturnedItemAsset((ItemAsset)Assets.find(EAssetType.ITEM, item.id));
     State         = new UnturnedItemState(item);
 }
        /// <summary>
        ///   Handles operation <see cref = "DestroyItem" />: Destroys an existing <see cref = "MmoItem" />.
        ///   The <see cref = "MmoItem.Owner" /> must be this actor instance.
        /// </summary>
        /// <param name = "peer">
        ///   The client peer.
        /// </param>
        /// <param name = "request">
        ///   The request.
        /// </param>
        /// <param name = "sendParameters">
        ///   The send Parameters.
        /// </param>
        /// <returns>
        ///   An <see cref = "OperationResponse" /> with error code <see cref = "ReturnCode.Ok" />, <see cref = "ReturnCode.ItemNotFound" /> or <see cref = "ReturnCode.ItemAccessDenied" />.
        /// </returns>
        public override OperationResponse Handle(MmoActor actor, OperationRequest request, SendParameters sendParameters)
        {
            var operation = new DestroyItem(actor.Peer.Protocol, request);

            if (!operation.IsValid)
            {
                return(new OperationResponse(request.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                });
            }

            operation.OnStart();
            Item item;
            bool actorItem = actor.TryGetItem(operation.ItemType, operation.ItemId, out item);

            if (actorItem == false)
            {
                IWorld world = actor.World;

                // search world cache just to see if item exists at all
                if (world.ItemCache.TryGetItem(operation.ItemType, operation.ItemId, out item) == false)
                {
                    return(operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound"));
                }
            }

            if (actorItem)
            {
                // we are already in the item thread, invoke directly
                return(ItemOperationDestroy(actor, item, operation));
            }

            // second parameter (peer) allows us to send an error event to the client (in case of an error)
            // error ItemAccessDenied or ItemNotFound will be returned
            item.Fiber.Enqueue(() => actor.ExecItemOperation(() => this.ItemOperationDestroy(actor, item, operation), sendParameters));

            // operation is continued later
            return(null);
        }
Exemplo n.º 4
0
        void HandleDestroyItem(DestroyItem destroyItem)
        {
            ushort pos = (ushort)((destroyItem.ContainerId << 8) | destroyItem.SlotNum);

            // prevent drop unequipable items (in combat, for example) and non-empty bags
            if (Player.IsEquipmentPos(pos) || Player.IsBagPos(pos))
            {
                InventoryResult msg = _player.CanUnequipItem(pos, false);
                if (msg != InventoryResult.Ok)
                {
                    _player.SendEquipError(msg, _player.GetItemByPos(pos));
                    return;
                }
            }

            Item pItem = _player.GetItemByPos(destroyItem.ContainerId, destroyItem.SlotNum);

            if (pItem == null)
            {
                _player.SendEquipError(InventoryResult.ItemNotFound);
                return;
            }

            if (pItem.GetTemplate().HasFlag(ItemFlags.NoUserDestroy))
            {
                _player.SendEquipError(InventoryResult.DropBoundItem);
                return;
            }

            if (destroyItem.Count != 0)
            {
                uint i_count = destroyItem.Count;
                _player.DestroyItemCount(pItem, ref i_count, true);
            }
            else
            {
                _player.DestroyItem(destroyItem.ContainerId, destroyItem.SlotNum, true);
            }
        }
        public override IEnumerable <object> Run()
        {
            GuildStorageManager storage = this.Entity.Storage;
            OnlineGuildMember   member  = this.Entity.GetOnlineMember(this.Operation.PuchasedCID);

            if (!this.Entity.Storage.Valid || !FeatureMatrix.IsEnable("GuildStorage"))
            {
                member.SendOperationFailedDialog("GuildStorageFail_Processing");
                storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid);
                this.Finished = true;
                yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] GuildStorage")
                {
                    Reason = FailMessage.ReasonCode.LogicalFail
                });
            }
            else if (this.Entity.Storage.Processing)
            {
                member.SendOperationFailedDialog("GuildStorageFail_Processing");
                storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Processing);
                this.Finished = true;
                yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] Entity.Storage.Processing")
                {
                    Reason = FailMessage.ReasonCode.LogicalFail
                });
            }
            else if (!this.Entity.Storage.IsEnabled)
            {
                member.SendOperationFailedDialog("GuildStorageFail_Stopped");
                storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid);
                this.Finished = true;
                yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] Entity.Storage.IsEnabled")
                {
                    Reason = FailMessage.ReasonCode.LogicalFail
                });
            }
            else if (storage.StorageCount >= storage.GuildStorageSlotsMax)
            {
                member.SendOperationFailedDialog("GuildStorageFail_Full");
                storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid);
                this.Finished = true;
                yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] storage.StorageCount")
                {
                    Reason = FailMessage.ReasonCode.LogicalFail
                });
            }
            else
            {
                this.Entity.Storage.Processing = true;
                int targetSlotCount = 0;
                if (this.Entity.Storage.StorageCount == 0 && !FeatureMatrix.IsEnable("GuildStoargeSlotAllCash"))
                {
                    storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.PurchaseSlotByGold);
                    if (FeatureMatrix.GetInteger("GuildStorageSlotGoldPrice") > 0)
                    {
                        DestroyItem   op   = new DestroyItem("gold", FeatureMatrix.GetInteger("GuildStorageSlotGoldPrice"), GiveItem.SourceEnum.Unknown);
                        OperationSync sync = new OperationSync()
                        {
                            Connection = member.PlayerConn,
                            Operation  = (Operation)op
                        };
                        yield return((object)sync);

                        if (!sync.Result || !op.Result)
                        {
                            this.Entity.Storage.Processing = false;
                            storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Error_PurchaseSlotByGold);
                            member.SendOperationFailedDialog("GuildStorageFail_PurchaseFailed");
                            this.Finished = true;
                            yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] op.Result")
                            {
                                Reason = FailMessage.ReasonCode.LogicalFail
                            });

                            yield break;
                        }
                    }
                    targetSlotCount = this.Entity.Storage.GuildStorageSlotsFirstPurchase;
                }
                else
                {
                    storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.PurchaseSlotByCash);
                    if (!FeatureMatrix.IsEnable("GuildStoargeSlotFree"))
                    {
                        if (this.Operation.ProductNo == -1)
                        {
                            member.SendOperationFailedDialog("GuildStorageFail_PurchaseFailed");
                            storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PickGuildItem, GuildStorageEventCode.Error_Invalid);
                            this.Entity.Storage.Processing = false;
                            this.Finished = true;
                            yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] Operation.ProductNo")
                            {
                                Reason = FailMessage.ReasonCode.LogicalFail
                            });

                            yield break;
                        }
                        else
                        {
                            DirectPickUpByProductNo op = new DirectPickUpByProductNo()
                            {
                                ProductNoList = new List <int>()
                                {
                                    this.Operation.ProductNo
                                },
                                IsCredit = this.Operation.IsCredit
                            };
                            OperationSync sync = new OperationSync()
                            {
                                Connection = member.CashShopConn,
                                Operation  = (Operation)op
                            };
                            yield return((object)sync);

                            if (!sync.Result || !op.Result || !op.ResultingItems.ContainsKey("guildstorage_ticket"))
                            {
                                storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Error_PurchaseSlotByCash);
                                member.SendOperationFailedDialog("GuildStorageFail_PurchaseFailed");
                                this.Entity.Storage.Processing = false;
                                this.Finished = true;
                                yield return((object)new FailMessage("[PurchaseGuildStorageProcessor] guildstorage_ticket")
                                {
                                    Reason = FailMessage.ReasonCode.LogicalFail
                                });

                                yield break;
                            }
                        }
                    }
                    targetSlotCount = this.Entity.Storage.GuildStorageSlotsPerPurchase;
                }
                storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Process);
                AddGuildStorageSlots requestOp = new AddGuildStorageSlots()
                {
                    SlotCount = targetSlotCount
                };
                requestOp.OnComplete += (Action <Operation>)(___ => this.Entity.Storage.StorageCount = requestOp.ResultSlotCount);
                OperationSync sync2 = new OperationSync()
                {
                    Connection = this.Entity.Storage.ItemConn,
                    Operation  = (Operation)requestOp
                };
                yield return((object)sync2);

                if (requestOp.Result)
                {
                    storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Done);
                }
                else
                {
                    storage.AddGuildStorageLedger(this.Operation.PuchasedCID, GuildStorageOperationCode.PurchaseGuildStorage, GuildStorageEventCode.Error_ProcessFail);
                }
                this.Entity.Storage.Processing = false;
                this.Entity.Storage.ReportExtendSlot(member.CharacterName, this.Entity.Storage.GuildStorageSlotsPerPurchase);
                this.Finished = true;
                yield return((object)new OkMessage());
            }
        }
Exemplo n.º 6
0
        public override void Parse(EndianBinaryReader reader)
        {
            ushort length;
            ushort id;

            byte[] content;

            if (!IsConnected() || tcpClient.Available == 0)
            {
                return;
            }

            var lengthBuffer = reader.ReadBytes(2);

            lengthBuffer = _proxy.Decrypt(lengthBuffer);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(lengthBuffer);
            }
            length = BitConverter.ToUInt16(lengthBuffer, 0);

            if (!IsConnected())
            {
                return;
            }

            content = _proxy.Decrypt(reader.ReadBytes(length));

            EndianBinaryReader cachedReader = new EndianBinaryReader(EndianBitConverter.Big, new MemoryStream(content));

            id = cachedReader.ReadUInt16();

            Console.WriteLine($"Received: {id}");

            switch (id)
            {
            case ServerVersionCheck.ID:
                ServerVersionCheck serverVersionCheck = new ServerVersionCheck(cachedReader);

                if (serverVersionCheck.compatible)
                {
                    Compatible?.Invoke(this, EventArgs.Empty);
                    Send(new ClientRequestCode());
                }
                else
                {
                    NotCompatible?.Invoke(this, EventArgs.Empty);
                    thread.Abort();
                }
                break;

            case ServerRequestCode.ID:
                ServerRequestCode serverRequestCode = new ServerRequestCode(cachedReader);
                Generator         generator         = new Generator();
                generator.Build(serverRequestCode.code);
                _proxy.InitStageOne(generator.Output);
                break;

            case ServerRequestCallback.ID:
                Console.WriteLine("Stage two received");
                ServerRequestCallback serverRequestCallback = new ServerRequestCallback(cachedReader);

                _proxy.InitStageTwo(serverRequestCallback.secretKey);

                Console.WriteLine("StageTwo initialized");

                Console.WriteLine("Sending login request");

                SendEncoded(new Ping());
                SendEncoded(new Login(api.Account.UserID, api.Account.SID, 0, api.Account.InstanceID));
                SendEncoded(new Ready());
                break;

            case BuildingInit.ID:
                BuildingInit buildingInit = new BuildingInit(cachedReader);
                lock (api.buildingsLocker)
                    api.Buildings.Add(new Building(buildingInit.BuildingID, buildingInit.Name, buildingInit.X, buildingInit.Y, buildingInit.AssetType));
                break;

            case DestroyBuilding.ID:
                DestroyBuilding destroyBuilding = new DestroyBuilding(cachedReader);
                lock (api.buildingsLocker)
                    api.Buildings.RemoveAll(building => building.BuildingID == destroyBuilding.BuildingID);
                break;

            case GateInit.ID:
                GateInit gateInit = new GateInit(cachedReader);
                api.Gates.Add(new Gate(gateInit.GateType, gateInit.X, gateInit.Y));
                break;

            case ShipDestroyed.ID:
                ShipDestroyed shipDestroyed = new ShipDestroyed(cachedReader);
                if (shipDestroyed.UserID == api.Account.UserID)
                {
                    Destroyed?.Invoke(this, EventArgs.Empty);
                }
                break;

            case Notify.ID:
                Notify notify = new Notify(cachedReader);
                if (notify.MessageType == "ttip_killscreen_basic_repair")
                {
                    Destroyed?.Invoke(this, EventArgs.Empty);
                }
                break;

            case MapChanged.ID:
                MapChanged mapChanged = new MapChanged(cachedReader);
                Console.WriteLine($"Map changed to: {mapChanged.MapID} | {mapChanged.var_294}");
                SendEncoded(new MapChangeConfirmation(true));
                break;

            case HeroInit.ID:
                HeroInit heroInit = new HeroInit(cachedReader);

                api.Boxes.Clear();
                api.MemorizedBoxes.Clear();
                api.Ores.Clear();
                api.Ships.Clear();
                api.Gates.Clear();
                api.Buildings.Clear();

                // Movement
                api.Account.X = heroInit.X;
                api.Account.Y = heroInit.Y;

                // Map statistics
                api.Account.HP             = (int)heroInit.HP;
                api.Account.MaxHP          = (int)heroInit.MaxHP;
                api.Account.Shield         = (int)heroInit.Shield;
                api.Account.MaxShield      = (int)heroInit.MaxShield;
                api.Account.NanoHP         = (int)heroInit.NanoHP;
                api.Account.MaxNanoHP      = (int)heroInit.MaxNanoHP;
                api.Account.FreeCargoSpace = (int)heroInit.FreeCargoSpace;
                api.Account.CargoCapacity  = (int)heroInit.CargoCapacity;

                // Ship
                api.Account.Shipname = heroInit.Shipname;
                api.Account.Speed    = (int)(heroInit.Speed * 0.97);

                // Statistics
                api.Account.Cloaked = heroInit.Cloaked;
                api.Account.Jackpot = heroInit.Jackpot;
                api.Account.Premium = heroInit.Premium;
                api.Account.Credits = heroInit.Credits;
                api.Account.Honor   = heroInit.Honor;
                api.Account.Uridium = heroInit.Uridium;
                api.Account.XP      = heroInit.XP;
                api.Account.Level   = (int)heroInit.Level;
                api.Account.Rank    = (int)heroInit.Rank;

                // Social
                api.Account.ClanID    = (int)heroInit.ClanID;
                api.Account.ClanTag   = heroInit.ClanTag;
                api.Account.FactionID = heroInit.FactionID;

                HeroInited?.Invoke(this, EventArgs.Empty);
                api.Account.Ready = true;
                Task.Delay(15000).ContinueWith(_ => api.Account.JumpAllowed = true);

                SendEncoded(new InitPacket(1));
                SendEncoded(new InitPacket(2));
                break;

            case 24328:     //CpuInitializationCommand
                SendEncoded(new OldStylePacket("JCPU|GET"));
                break;

            case DroneFormationUpdated.ID:
                DroneFormationUpdated droneFormationUpdated = new DroneFormationUpdated(cachedReader);
                break;

            case ShipUpdated.ID:
                ShipUpdated shipUpdated = new ShipUpdated(cachedReader);
                api.Account.UpdateHitpointsAndShield(shipUpdated.HP, shipUpdated.Shield, shipUpdated.NanoHP);
                break;

            case ShieldUpdated.ID:
                ShieldUpdated shieldUpdated = new ShieldUpdated(cachedReader);
                api.Account.UpdateShield(shieldUpdated.Shield, shieldUpdated.MaxShield);
                break;

            case CargoUpdated.ID:
                CargoUpdated cargoUpdated = new CargoUpdated(cachedReader);
                api.Account.FreeCargoSpace = api.Account.CargoCapacity - (int)cargoUpdated.CargoCount;
                break;

            case HitpointsUpdated.ID:
                HitpointsUpdated hitpointsUpdated = new HitpointsUpdated(cachedReader);
                api.Account.UpdateHitpoints(hitpointsUpdated.HP, hitpointsUpdated.MaxHP, hitpointsUpdated.NanoHP, hitpointsUpdated.MaxNanoHP);
                break;

            case ShipAttacked.ID:
                ShipAttacked shipAttacked = new ShipAttacked(cachedReader);
                Attacked?.Invoke(this, shipAttacked);
                break;

            case ShipInit.ID:
                ShipInit shipInit = new ShipInit(cachedReader);
                Ship     newShip  = new Ship();
                newShip.UserID   = (int)shipInit.UserID;
                newShip.Username = shipInit.Username;
                newShip.NPC      = shipInit.NPC;

                // Movement
                newShip.X = shipInit.X;
                newShip.Y = shipInit.Y;

                // Ship
                newShip.Shipname = shipInit.Shipname;

                // Statistics
                newShip.Cloaked = shipInit.Cloaked;

                // Social
                newShip.ClanID    = (int)shipInit.ClanID;
                newShip.ClanTag   = shipInit.ClanTag;
                newShip.FactionID = (int)shipInit.FactionID;
                lock (api.shipsLocker)
                    api.Ships.Add(newShip);
                break;

            case ShipMove.ID:
                ShipMove shipMove = new ShipMove(cachedReader);
                ShipMoving?.Invoke(this, shipMove);
                break;

            case BoxInit.ID:
                BoxInit boxInit = new BoxInit(cachedReader);
                if (boxInit.Hash.Length != 5)
                {
                    Box box = new Box(boxInit.Hash, boxInit.X, boxInit.Y, boxInit.Type);
                    lock (api.boxesLocker) lock (api.memorizedBoxesLocker)
                        {
                            api.Boxes.Add(box);
                            api.MemorizedBoxes.Add(box);
                        }
                }
                break;

            case DestroyItem.ID:
                DestroyItem item = new DestroyItem(cachedReader);
                lock (api.boxesLocker) lock (api.memorizedBoxesLocker)
                    {
                        api.Boxes.RemoveAll(box => box.Hash == item.Hash);
                        if (item.CollectedByPlayer)
                        {
                            api.MemorizedBoxes.RemoveAll(box => box.Hash == item.Hash);
                        }
                    }
                lock (api.oresLocker)
                    api.Ores.RemoveAll(ore => ore.Hash == item.Hash);
                break;

            case DestroyShip.ID:
                DestroyShip destroyedShip = new DestroyShip(cachedReader);
                lock (api.Ships)
                    api.Ships.RemoveAll(ship => ship.UserID == destroyedShip.UserID);
                break;

            case OreInit.ID:
                OreInit oreInit = new OreInit(cachedReader);
                lock (api.oresLocker)
                    api.Ores.Add(new Ore(oreInit.Hash, oreInit.X, oreInit.Y, oreInit.Type));
                break;

            case 17162:
                if (!pingThread.IsAlive)
                {
                    pingThread = new Thread(new ThreadStart(PingLoop));
                    pingThread.Start();
                }
                break;

            case OldStylePacket.ID:
                OldStylePacket oldStylePacket  = new OldStylePacket(cachedReader);
                string[]       splittedMessage = oldStylePacket.Message.Split('|');
                switch (splittedMessage[1])
                {
                case OldPackets.SELECT:
                    switch (splittedMessage[2])
                    {
                    case OldPackets.CONFIG:
                        api.Account.Config = Convert.ToInt32(splittedMessage[3]);
                        break;
                    }
                    break;

                case OldPackets.PORTAL_JUMP:
                    Console.WriteLine($"(Old) Map changed to: {splittedMessage[2]}");
                    SendEncoded(new MapChangeConfirmation(true));
                    break;

                case OldPackets.LOG_MESSAGE:
                    switch (splittedMessage[3])
                    {
                    case OldPackets.BOX_CONTENT_CREDITS:
                        api.Account.CollectedCredits += double.Parse(splittedMessage[4]);
                        break;

                    case OldPackets.BOX_CONTENT_URIDIUM:
                        api.Account.CollectedUridium += double.Parse(splittedMessage[4]);
                        break;

                    case OldPackets.BOX_CONTENT_EE:
                        api.Account.CollectedEE += int.Parse(splittedMessage[4]);
                        break;

                    case OldPackets.BOX_CONTENT_XP:
                        api.Account.CollectedXP += double.Parse(splittedMessage[4]);
                        break;

                    case OldPackets.BOX_CONTENT_HON:
                        api.Account.CollectedHonor += double.Parse(splittedMessage[4]);
                        break;
                    }
                    LogMessage?.Invoke(this, string.Join("|", splittedMessage));
                    break;

                default:
                    Console.WriteLine("Received unsupported old style packet with message: {0}", oldStylePacket.Message);
                    break;
                }
                break;

            default:
                Console.WriteLine("Received packet of ID {0} with total size of {1} which is not supported", id, length + 4);
                break;
            }
        }