private void OnSend(IAsyncResult asyncResult) { Socket s = (Socket)asyncResult.AsyncState; if (s == null || s.Connected == false) { ServerConsole.DebugLine("socket null or connection closed"); Dispose(); return; } try { int bytes = s.EndSend(asyncResult); if (bytes <= 0) { Dispose(false); return; } UpdateAcitivty(); if (mCoalesceSleep > 0) { Thread.Sleep(mCoalesceSleep); } } catch (Exception ex) { ExceptionHandler.Trace(ex); Dispose(false); } }
/// Request to walk /// 0x00A7 9: public static void WalkToXY(NetState state, PacketReader reader) { if (state.IsValid(EAccountState.World) == false) { state.Disconnect(); return; } // TODO: this is the worst system i've ever seen.. // we receive the FINAL position instead of step by step packets // and have to search a path to the final position // if a path has been found, we walk it step by step // this is done using a Timer.. Character c = state.Account.ActiveChar; int unkInt = reader.ReadInt32(); // Since 2008-08-27aRagexeRE, X/Y starts at pos 6 byte b1 = reader.ReadByte(); byte b2 = reader.ReadByte(); byte b3 = reader.ReadByte(); int x = b1 * 4 + (b2 >> 6); int y = ((b2 & 63) << 4) + (b3 >> 4); ServerConsole.DebugLine("WalkToXY: from " + c.Location.X + "/" + c.Location.Y + " to " + x + "/" + y); WalkingHelper.WalkToXY(c, new Point2D(x, y)); }
public static void OnWorldLoadFinish() { Thread.Sleep(1000); ServerConsole.DebugLine("ThreadTest: Initialize called! Thread will sleep 5secs..."); Thread.Sleep(5000); ServerConsole.DebugLine("ThreadTest: Initialize released!"); }
public List <ICharacterInfo> GetCharacterInfos(IAccountInfo account, IServerDescription server) { ServerConsole.DebugLine("Auth-server requested character list for account: {0}", account.Username); return(new List <ICharacterInfo>(new[] { new CharacterInfo(815, "Test Character") })); }
public List <IServerDescription> GetServerDescriptions() { ServerConsole.DebugLine("Auth-server requested server descriptions of known world server types.."); // @TODO: Get list of world servers here return(new List <IServerDescription>(new [] { new ServerDescription("Test server") })); }
/// <summary> /// Invoked by the client including the parameter. /// </summary> /// <param name="poco"></param> public void SomeRemoteMagic(SimplePoco poco) { ServerConsole.DebugLine("Recv poco obj from client! {0}: {1}", poco.Id, poco.Title); Debug.WriteLine(poco); // Get client proxy and invoke a answer to the poco var proxy = CurrentClient.GetClientProxy <ITestClient>(); proxy.SomeClientMagic("Got your poco, ty client!"); }
public static bool ValidateMessage(NetState state, string text, out string username, out string message) { // Delimiter for <username> and <message> // and yep, this means, the client sends us "Username : message" as one string // so we have to parse it.. string delim = " : "; username = ""; message = ""; // TODO: i saw a topic in eA source request about fakename talking // he wanted to display the fakename in the chat // if implementing such a mod, we should check here for the fakename too! if (text.StartsWith(state.ActiveChar.Status.Name + delim) == false) { // This is just to check for a hacked packet // The message always has to start with <username><delimiter>, so its incorrect either @ this point if (text.StartsWith(state.ActiveChar.Status.Name) == false) { ServerConsole.DebugLine("Chatting.ValidateMessage: Player '{0}' sent a message using an incorrect name! Forcing a relog...", state.ActiveChar.Status.Name); state.Dispose(); } return(false); } // Split by delimiter string[] messageParts = text.Split(new string[] { delim }, StringSplitOptions.None); // Just in case.. if (messageParts.Length != 2) { return(false); } // TODO: couldnt trim here to not modify the message, but i should.. maybe.. or not? o.o username = messageParts[0]; message = messageParts[1]; // Remove |00 if (message.StartsWith("|00") == true) { message = message.Substring(3); } // TODO: We didnt have max size for message as eAthena // but the client has (max display size is 254 + 1) // so.. ? o.o if (message.Length >= Global.CHAT_SIZE_MAX) { ServerConsole.WarningLine("Chatting.ValidateMessage: Message is to long! Max {0} length, msg has {1}: {2}", Global.CHAT_SIZE_MAX, message.Length, message); message = message.Substring(0, Global.CHAT_SIZE_MAX - 1); } return(true); }
public static void OnServerStarted() { // Spawn test ServerConsole.DebugLine("Spawn a mob"); Location location = new Location(1, new Point2D(157, 183)); Monster.SpawnOnce(null, location, "Rovolution Poring", 1002, 1); ServerConsole.DebugLine("Spawn a npc"); location = new Location(1, new Point2D(155, 183)); NpcScript.Spawn("Test NPC", 46, location); }
public IEnumerable <IServerDescription> GetServerDescriptions() { ServerConsole.DebugLine("Client requests server descriptions"); var currentAccount = GetCurrentAccount(); if (currentAccount == null) { throw new NotLoggedInException(); } return(_interClient.GetServerDescriptions()); }
public static void Main(string[] args) { var endPoint = ProtocolEndPointBase.CreateEndPoint("tcp://127.0.0.1:13378"); _server = ServiceBuilder.CreateService(endPoint); _server.AddService <ITestServerService, TestServerService>(new TestServerService()); _server.ClientConnected += ServerOnClientConnected; _server.ClientDisconnected += ServerOnClientDisconnected; _server.Start(); ServerConsole.DebugLine("Service running on {0}", endPoint); Console.Read(); }
public IAccountInfo ClientLogin(string username, string password) { ServerConsole.DebugLine("Client login: {0} @ {1}", username, password); var accountInfo = new AccountInfo(1337, username, password); // Same key twice means the same connection logged in again // @TODO: Verify this about not beeing a hack if (_knownAcccounts.ContainsKey(CurrentClient)) { _knownAcccounts.Remove(CurrentClient); } _knownAcccounts.Add(CurrentClient, accountInfo); return(accountInfo); }
public IEnumerable <ICharacterInfo> SelectServer(IServerDescription server) { ServerConsole.DebugLine("Client selected server: {0}", server.Name); var currentAccount = GetCurrentAccount(); if (currentAccount == null) { throw new NotLoggedInException(); } var characters = _interClient.GetCharacterInfos(currentAccount, server); ServerConsole.DebugLine("Returning {0} character infos..", characters.Count()); return(characters); }
public static void Main(string[] args) { // Try access a config var conf = Factory.Create <Provider>("server-conf.xml"); var dynConf = conf.AsExpando().configuration; // Prepare console for a large output var width = Math.Min(100, Console.LargestWindowWidth - 2); Console.CursorVisible = false; Console.Clear(); Console.WindowLeft = Console.WindowTop = 0; if (Console.WindowWidth < width) { Console.WindowWidth = width; } Console.Title = "Simple TCP message server test"; // Create a test server _server = new SimpleTcpMessageServer(dynConf.network.host, dynConf.network.port); _server.Start(); do { var cmd = Console.ReadLine(); if (cmd == "exit") { _server.Stop(); } if (cmd == "testmsg") { var msg = new TextMessage("Hello from server! äöüß"); _server.Broadcast(msg); } if (cmd == "testobj") { var msg = new TextMessage("Hello from server! äöüß"); _server.Broadcast(msg); } } while (_server.IsActive); ServerConsole.DebugLine("Press any key to exit."); Console.Read(); }
protected override void ClientOnMessageReceived(object sender, MessageEventArgs args) { base.ClientOnMessageReceived(sender, args); var client = sender as IServerClient; if (client == null) { throw new ArgumentNullException("sender", "Internal server error - sender-client can not be null"); } // Simple debug var textMessage = args.Message as TextMessage; if (textMessage != null) { ServerConsole.DebugLine("[{0}] RECV: {1}", client.RemoteEndPoint, textMessage.Text); } else { ServerConsole.DebugLine("[{0}] RECV: {1}", client.RemoteEndPoint, args.Message.GetType()); } }
public static void OnWorldLoadFinish() { ServerConsole.DebugLine("global Event OnWorldLoadFinish called :O"); }
public static void Main(string[] args) { // Try access a config var serverConfiguration = Factory.Create <Provider>("conf/server.xml"); var dynamicConfig = serverConfiguration.FirstAsExpando().configuration; // Prepare console for a large output #if WINDOWS var width = Math.Min(100, Console.LargestWindowWidth - 2); Console.CursorVisible = false; Console.Clear(); Console.WindowLeft = Console.WindowTop = 0; if (Console.WindowWidth < width) { Console.WindowWidth = width; } #endif var ver = Assembly.GetExecutingAssembly().GetName().Version; Console.Title = string.Format("Zeus auth-server v{0}.{1}", ver.Major, ver.Minor); ServerConsole.StatusLine(Console.Title); // Create inter-server listener service string interServerEndPointAddress = string.Format("tcp://{0}:{1}", dynamicConfig.network.inter_server.host, dynamicConfig.network.inter_server.port); var interServerEndPoint = ProtocolEndPointBase.CreateEndPoint(interServerEndPointAddress); ServerConsole.Info("Start connecting to inter-server.."); // @TODO: Is any action coming from inter-server to auth-server? // @TODO: Create inter -> auth service (character goes back to char select) _interClient = ServiceClientBuilder.CreateClient <IAuthService>(interServerEndPoint, new ServerServiceImplementation()); _interClient.Connected += (o, a) => { ServerConsole.WriteLine(ServerConsoleColor.Status, " successfull!"); // AuthServerLogin _interClient.ServiceProxy.AuthServerLogin((string)dynamicConfig.network.inter_server.password); }; _interClient.Disconnected += delegate { ServerConsole.ErrorLine("Connection to inter-server lost."); // @TODO: Reconnect? }; _interClient.ConnectTimeout = 30; _interClient.Connect(); // Create a client listener service string endPointAddress = string.Format("tcp://{0}:{1}", dynamicConfig.network.host, dynamicConfig.network.port); _clientService = ServiceBuilder.CreateService(ProtocolEndPointBase.CreateEndPoint(endPointAddress)); _clientService.ClientConnected += (sender, clientEventArgs) => ServerConsole.DebugLine("Client connected #{0}", clientEventArgs.Client.ClientId); _clientService.ClientDisconnected += (sender, clientEventArgs) => ServerConsole.DebugLine("Client disconnected #{0}", clientEventArgs.Client.ClientId); // Add interface for client connections var clientService = new ClientServiceImplementation(_interClient.ServiceProxy); _clientService.AddService <IClientService, ClientServiceImplementation>(clientService); // Start listener service _clientService.Start(); ServerConsole.StatusLine("Auth-server is listening to: {0}", endPointAddress); do { var cmd = Console.ReadLine(); if (cmd == "exit") { _clientService.Stop(); } } while (_clientService.Connected); ServerConsole.WarningLine("Press any key to exit."); Console.Read(); }
public static void OnServerStarted() { ServerConsole.DebugLine("global Event OnServerStarted called :O"); }
public static void WalkToXY_Tick(WorldObjectUnit obj) { if (obj.Walkpath == null) { return; } else if (obj.Walkpath.path_pos >= obj.Walkpath.path_len) { return; } else if (obj.Walkpath.path[obj.Walkpath.path_pos] == EDirection.None) { return; } else if ((int)obj.Walkpath.path[obj.Walkpath.path_pos] > 8) { return; } else { } // TODO: this is the point there the client seems to look laggy // eAthena sends before any movement the WalkOk() packet // and the client animates the move to the target location. // But if we attacked by a skill or w00tever, // eAthena updates the position (i think) // AND THIS is the all-known movement/position-reset. // // In future, we may test to send a WalkOk() Packet in every single step // So the client maybe display it more accurate.. EDirection dir = obj.Walkpath.path[obj.Walkpath.path_pos]; Point2D targetLoc = obj.Location.Point + dir.ToPoint2D(); ServerConsole.DebugLine("{0}: walk from {1} to {2} ({3})", obj, obj.Location.Point, targetLoc, dir); //obj.Map.DrawGat(); //Mapcache.Maps[obj.Map.Name].DrawGat(); if (obj.Map.CheckCell(targetLoc, ECollisionType.Walkable) == false) { // Target location is not walkable - recalc path! ServerConsole.DebugLine("WalkToXY_Tick: location {0} not walkable, recalc path..", targetLoc); WalkToXY(obj, obj.TargetLocation); return; } obj.Move(dir); obj.Walkpath.path_pos++; int speed = CalcWalkspeed(obj); // Next step? if (speed > 0) { obj.WalkTimer = Timer.DelayCall(TimeSpan.FromMilliseconds(speed), TimeSpan.Zero, 1, new TimerStateCallback <WorldObjectUnit>(WalkToXY_Tick), obj); } else { // No next step, target location reached, update target location // just to be sure.. obj.TargetLocation = obj.Location.Point; obj.Walkpath = null; ServerConsole.DebugLine("WalkToXY_Tick: finished moving to location {0}", obj.Location.Point); } }
public bool HandleReceive(NetState ns) { if (ns == null || ns.Running == false) { return(false); } ByteQueue buffer = ns.Buffer; if (buffer == null || buffer.Length <= 0) { return(true); } ServerConsole.DebugLine("{0}: Incoming data, {1} bytes", ns, buffer.Length); /* * Packet Analyse/verify && Parsing */ lock (buffer) { int turns = 0; int length = buffer.Length; while (length > 0 && ns != null && ns.Running) { short packetID = buffer.GetPacketID(); #if DEBUG_PACKETS // debug log using (TextWriter writer = File.CreateText(AppDomain.CurrentDomain.BaseDirectory + @"\packet_" + DateTime.Now.UnixTimestamp() + ".log")) { using (MemoryStream ms = new MemoryStream(buffer.ByteBuffer)) Tools.FormatBuffer(writer, ms, (int)ms.Length); } #endif PacketHandler handler = PacketHandlers.GetHandler(packetID); if (handler == null) { byte[] data = new byte[length]; length = buffer.Dequeue(data, 0, length); // Log unknown packets string unknownPacketPath = AppDomain.CurrentDomain.BaseDirectory + @"\packet_" + packetID.ToString("X4") + ".log"; if (File.Exists(unknownPacketPath) == false) { using (TextWriter writer = File.CreateText(unknownPacketPath)) { writer.WriteLine("Unknown packet 0x" + packetID.ToString("X4") + ", length " + length); using (MemoryStream ms = new MemoryStream(data)) { Tools.FormatBuffer(writer, ms, (int)ms.Length); } } } ServerConsole.WarningLine("{0}: P {1:X4}, {2} bytes, no Handler found!", ns, packetID, length); break; } ServerConsole.StatusLine("{0}: [{1}] P {2:X4}, {3} bytes, handled {4}", ns, handler.Name, packetID, length, handler.Length); byte[] packetBuffer; // If we set the length to -1 (dynamic packet length), read the full buffer int bufferLength = (handler.Length > 0 ? handler.Length : length); if (bufferLength < mBufferSize) { packetBuffer = mBuffers.AcquireBuffer(); } else { packetBuffer = new byte[bufferLength]; } buffer.Dequeue(packetBuffer, 0, bufferLength); PacketReader r = new PacketReader(packetBuffer, bufferLength, 0, true); handler.OnReceive(ns, r); length -= bufferLength; if (bufferLength < mBufferSize) { mBuffers.ReleaseBuffer(packetBuffer); } else { packetBuffer = null; } turns++; } // end while()*/ } // end Lock() // Clear internal byte buffer for receive data if (ns != null && ns.Buffer != null) { ns.Buffer.Clear(); } return(true); }
public virtual void Send(Packet p) { if (mSocket == null || mBlockAllPackets) { ServerConsole.ErrorLine("{0}: Socket is null! Packet {1:X4} ({2} bytes) cant be send", this, p.PacketID, p.Length); // Wont send packet, but trigger OnSend to free data.. p.OnSend(this); Dispose(); return; } // Allow APIs to break sending if (p.OnBeforeSend(this) == false) { // Didnt send the packet, so let the APIs know that (2nd param, false) p.OnSend(this, false); return; } PacketSendProfile prof = PacketSendProfile.Acquire(p.GetType()); int length = 0; byte[] buffer = p.Compile(out length); if (buffer == null) { ServerConsole.ErrorLine("{0}: null buffer send, disconnecting...", this); using (StreamWriter op = new StreamWriter("null_send.log", true)) { op.WriteLine("{0} Client", "{1}: null buffer send, disconnecting...", DateTime.Now, this); op.WriteLine(new System.Diagnostics.StackTrace()); } Dispose(); return; } if (buffer.Length <= 0 || length <= 0) { p.OnSend(this); return; } if (prof != null) { prof.Start(); } if (mEncoder != null) { mEncoder.EncodeOutgoingPacket(this, ref buffer, ref length); } try { ServerConsole.DebugLine("{0}: sending Packet 0x{1:X4} ({2} bytes)", this, p.PacketID, length); mSocket.BeginSend(buffer, 0, length, SocketFlags.None, mOnSend, mSocket); } catch (Exception ex) { ExceptionHandler.Trace(ex); Dispose(false); } p.OnSend(this); if (prof != null) { prof.Finish(length); } }
/// First packet after selecting a character /// 0x0436 19: <accountID>.L <charID>.L <loginID1>.L <clientTick>.L <sex>.B public static void WantToConnect(NetState state, PacketReader reader) { int accountID = reader.ReadInt32(); int charID = reader.ReadInt32(); int loginID1 = reader.ReadInt32(); int clientTick = reader.ReadInt32(); byte iSex = reader.ReadByte(); EAccountSex sex = (EAccountSex)iSex; state.Account = (Account)World.Objects[EDatabaseType.Account, accountID]; if (state.Account == null || state.Account.AccountState != EAccountState.Char) { ServerConsole.DebugLine("Invalid account or account state: {0}", (state.Account != null ? state.Account.AccountState.ToString() : "null")); state.Disconnect(); return; } if (state.Account.LoginID1 != loginID1 || state.Account.Sex != sex) { ServerConsole.DebugLine("Invalid loginID or sex: {0} != {1}; {2} != {3}", state.Account.LoginID1, loginID1, state.Account.Sex, sex); state.Disconnect(); return; } if (state.Account.ActiveChar == null || state.Account.ActiveChar.ID != charID) { ServerConsole.DebugLine("Invalid active character or charID: {0}", (state.ActiveChar != null ? state.ActiveChar.ID.ToString() : "null")); state.Disconnect(); return; } // Seems to be valid, save the netstate state.Account.Netstate = state; long tick = Timer.Ticks; // Mark as authed state.Account.AccountState = EAccountState.World; // pc_setnew state.ActiveChar.Status.Sex = state.Account.Sex; state.ActiveChar.LoginID1 = loginID1; state.ActiveChar.LoginID2 = 0; state.ActiveChar.ClientTick = clientTick; state.ActiveChar.State.Active = false; //Is set to true after player is fully authed and loaded state.ActiveChar.CanLogTick = tick; // Required to prevent homunculus copuing a base speed of 0 state.ActiveChar.BattleStatus.Speed = (ushort)Global.DEFAULT_WALK_SPEED; // pc_authok if (state.ActiveChar.Status.HP == 0) { state.ActiveChar.SetDead(); } state.ActiveChar.State.ConnectNew = true; state.ActiveChar.FollowTimer = null; state.ActiveChar.InvisibleTimer = null; state.ActiveChar.NpcTimer = null; state.ActiveChar.PvpTimer = null; state.ActiveChar.CanUseItemTick = tick; state.ActiveChar.CanUseCashFoodTick = tick; state.ActiveChar.CanEquipTick = tick; state.ActiveChar.CanTalkTick = tick; state.ActiveChar.CanSendMailTick = tick; state.ActiveChar.SpiritTimer = new List <Timer>(); state.ActiveChar.AutoBonus.Clear(); state.ActiveChar.AutoBonus2.Clear(); state.ActiveChar.AutoBonus3.Clear(); if (Config.ItemAutoGet) { state.ActiveChar.State.Autoloot = 10000; } if (Config.DispExperience) { state.ActiveChar.State.Showexp = true; } if (Config.DispZeny) { state.ActiveChar.State.Showzeny = true; } if ((Config.DisplaySkillFail & 2) > 0) { state.ActiveChar.State.Showdelay = true; } // Check and move equip //pc_setinventorydata(sd); for (int i = 0; i < state.ActiveChar.Status.Inventory.Count; i++) { } //pc_setequipindex(sd); // status_change_init here! // Note: eAthena dosnt realy init the status here, just memset() all to 0 // TODO: why did i set StatusChange.Clear() HERE? confirm this.. state.ActiveChar.StatusChange.Clear(); // TODO: implement player commands (eAthenas @commands) //if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && (pc_isGM(sd) >= get_atcommand_level(atcommand_hide))) // sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE); //else state.ActiveChar.Status.Option &= EStatusOption.Mask; state.ActiveChar.StatusChange.Option = state.ActiveChar.Status.Option; // This is the actual option used in battle // Set here because we need the inventory data for weapon sprite parsing state.ActiveChar.ViewData = WorldObjectViewData.GetViewData(state.ActiveChar.Status, (int)state.ActiveChar.Status.Class); // Set base timer for walkable units (from unit_setdata) // TODO: maybe this should be placed in a WorldObjectUnit-method to be used for every walkable unit.. state.ActiveChar.WalkTimer = null; state.ActiveChar.ActiveSkillTimer = null; state.ActiveChar.AttackTimer = null; state.ActiveChar.AttackableTick = state.ActiveChar.CanActTick = state.ActiveChar.CanMoveTick = tick; // clif_authok crap state.ActiveChar.GuildPosition = new Point2D(-1, -1); // Event timer state.ActiveChar.EventTimer = new List <Timer>(); // Rental Timer state.ActiveChar.RentalTimer = null; state.ActiveChar.HateMob = new short[3] { -1, -1, -1 }; // Character enters the map block // TODO: Position checking state.ActiveChar.Location.Map.OnEnter(state.ActiveChar); /* * if ((i = pc_setpos(sd, sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT)) != 0) { * ShowError("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i); * * // try warping to a default map instead (church graveyard) * if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != 0) { * // if we fail again * clif_authfail_fd(sd->fd, 0); * return false; * } * } */ // Let the client know that the authendication was successfull state.Send(new WorldResponseAuthOK(state.Account)); // eA puts the "char logged in" message here.. // TODO: send friend list // TODO: message about expired accounts, night flag // TODO: request registry // or dont need an async load of registry? state.ActiveChar.DieCounter = -1; }
/// <summary> /// Locates a random spare cell around the object given, using range as max /// distance from that spot. Used for warping functions. Use range below 0 for whole map range. /// </summary> /// <param name="src">src can be null as long as flag&1</param> /// <param name="p">Source poition to use (if flag & 1), will also contain the new position</param> /// <param name="rx">Range width</param> /// <param name="ry">Range height</param> /// <param name="flag"> /// <para>&1 = random cell must be around given m,x,y, not around src</para> /// <PARA>&2 = the target should be able to walk to the target tile</para> /// <para>&4 = there shouldn't be any players around the target tile (use the no_spawn_on_player setting)</para> /// </param> /// <returns></returns> public bool SearchFreeCell(WorldObjectUnit src, ref Point2D p, int rx, int ry, int flag) { int tries, spawn = 0; int bx, by; int rx2 = 2 * rx + 1; int ry2 = 2 * ry + 1; if (src == null && ((flag & 1) != 1 || (flag & 2) != 2)) { ServerConsole.DebugLine("SearchFreeCell: Incorrect usage! When src is NULL, flag has to be &1 and can't have &2"); return(false); } if ((flag & 1) == 1) { bx = p.X; by = p.Y; } else { bx = src.X; by = src.Y; } // No range? Return the target cell then.... if (rx == 0 && ry == 0) { p.X = bx; p.Y = by; return(CheckCell(p, ECollisionType.Reachable)); } // Calc max tries if (rx >= 0 && ry >= 0) { tries = rx2 * ry2; if (tries > 100) { tries = 100; } } else { tries = Width * Height; if (tries > 500) { tries = 500; } } Random rand = new Random(); while (tries-- > 0) { p.X = (rx >= 0 ? (rand.Next() % rx2 - rx + bx) : (rand.Next() % (Width - 2) + 1)); p.Y = (ry >= 0 ? (rand.Next() % ry2 - ry + by) : (rand.Next() % (Height - 2) + 1)); // Avoid picking the same target tile if (p.X == bx && p.Y == by) { continue; } if (CheckCell(p, ECollisionType.Reachable) == true) { if ((flag & 2) == 2 && src.CanReach(p, 1) == false) { continue; } if ((flag & 4) == 4) { // Limit of retries reached. if (spawn >= 100) { return(false); } /* * if (spawn++ < battle_config.no_spawn_on_player && * map_foreachinarea(map_count_sub, m, * x-AREA_SIZE, *y-AREA_SIZE, * x+AREA_SIZE, *y+AREA_SIZE, BL_PC) * ) * continue; */ } return(true); } } p.X = bx; p.Y = by; return(false); }
public static void OnWorldLoadFinish() { ServerConsole.DebugLine("PrioTest -> 0"); }