modernuo / modernuo Goto Github PK
View Code? Open in Web Editor NEWUltima Online Server Emulator for the modern era!
Home Page: https://www.modernuo.com
License: GNU General Public License v3.0
Ultima Online Server Emulator for the modern era!
Home Page: https://www.modernuo.com
License: GNU General Public License v3.0
Add separate native libraries for each supported linux flavor:
This line is not compiled under mono.
NativeReader.Read( m_Statics.Handle, pTiles, length );
When attempting to load one of the distribution json spawner files the server will crash with the following, e.g. [generatespawners felucca.json
System.Text.Json.JsonException: The JSON value could not be converted to System.Collections.Generic.List`1[Server.Json.DynamicJson]. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
at System.Text.Json.JsonSerializer.HandleStartObject(JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
at System.Text.Json.JsonSerializer.ReadCore(Type returnType, JsonSerializerOptions options, Utf8JsonReader& reader)
at System.Text.Json.JsonSerializer.Deserialize(String json, Type returnType, JsonSerializerOptions options)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at Server.Json.JsonConfig.Deserialize[T](String filePath, JsonSerializerOptions options) in /home/jabin/sources/ModernUO/Projects/Server/JsonConfiguration/JsonConfig.cs:line 60
at Server.Engines.Spawners.GenerateSpawners.GenerateSpawners_OnCommand(CommandEventArgs e) in /home/jabin/sources/ModernUO/Projects/UOContent/Engines/Spawners/GenerateSpawners.cs:line 45
at Server.CommandSystem.Handle(Mobile from, String text, MessageType type) in /home/jabin/sources/ModernUO/Projects/Server/Commands.cs:line 222
at Server.Mobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue) in /home/jabin/sources/ModernUO/Projects/Server/Mobile.cs:line 4866
at Server.Mobiles.PlayerMobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue) in /home/jabin/sources/ModernUO/Projects/UOContent/Mobiles/PlayerMobile.cs:line 1998
at Server.Network.PacketHandlers.UnicodeSpeech(NetState state, PacketReader pvSrc) in /home/jabin/sources/ModernUO/Projects/Server/Network/PacketHandlers.cs:line 1324
at Server.Network.MessagePumpService.DoWork() in /home/jabin/sources/ModernUO/Projects/Server/Network/MessagePumpService.cs:line 52
at Server.Core.RunEventLoop(IMessagePumpService messagePumpService) in /home/jabin/sources/ModernUO/Projects/Server/Main.cs:line 424
However loading the region-spawners.json
works fine.
There are several places where arrays are temporarily used. These arrays come from one or another type of pooling, are allocated as a managed array, or use a statically initialized array that violates thread safety.
These instances should be replaced with stackalloc or equiv techniques.
During the automatic cleanup many files were converted from other wrong encodings back to UTF-8. This process corrupted many comments (mainly localization text). This should be fixed by pasting back the proper text.
@jaedan had a great idea to integrate libuv using it as the engine loop and socket system.
This would give us the added performance like ASPNET Core.
Looks like libuv is being deprecated and the performance of managed sockets should be good enough.
Let's go back to regular sockets and wire that to a custom pipe in order to simplify the flow. It should look something like this:
Tangentially will need to decide if we use libuv for the thread and/or timers.
Update items.cfg
, mobiles.cfg
, and objects.json
.
Come up with a better way to categorize items/mobiles without having to list them.
Hover/Single-click is not showing OPL.
Like the title says. Build is not working on Windows systems. Also publish is not copying the Assemblies to its output path.
Add support for the Intel Performance Platform version of Zlib.
I am hesitant to use JTK's version because of reported issues.
If someone wants to optimize 1.2.8 or 1.2.11.1 with Intel IPP, that would be amazing!
Use Microsoft.Extensions.Logging
to create a logging system.
Replace Console.WriteLine with Logging
Related to #182, when the client attempts to sell to a vendor nothing happens.
The packet handler attempts to use the PacketReader.Length
property in order to verify the packet is valid. However as the backing IMemoryOwner<byte>
block for PacketReader
always has a length of 4096 due to SlabMemoryPool
's Rent(int size)
implementation ignoring the size parameter and only returning memory blocks of the default size (4096). This causes the calculated length check to always return false making the sell request fail:
public static void VendorSellReply(NetState state, PacketReader pvSrc)
{
Serial serial = pvSrc.ReadUInt32();
var vendor = World.FindMobile(serial);
if (vendor == null) return;
if (vendor.Deleted || !Utility.RangeCheck(vendor.Location, state.Mobile.Location, 10))
{
state.Send(new EndVendorSell(vendor));
return;
}
int count = pvSrc.ReadUInt16();
if (count < 100 && pvSrc.Length == 4 + 2 + count * 6) // pvSrc.Length is always 4096
{
var sellList = new List<SellItemResponse>(count);
for (var i = 0; i < count; i++)
{
var item = World.FindItem(pvSrc.ReadUInt32());
int amount = pvSrc.ReadInt16();
if (item != null && amount > 0)
sellList.Add(new SellItemResponse(item, amount));
}
if (sellList.Count > 0 && vendor is IVendor v && v.OnSellItems(state.Mobile, sellList))
state.Send(new EndVendorSell(vendor));
}
}
A workaround can be achieved by ensuring the packet header (Id + Length) doesn't get sliced by ProcessPacket
(see #182) and then manually reading the length to use in the check:
public static void VendorSellReply(NetState state, PacketReader pvSrc)
{
pvSrc.Seek(1, SeekOrigin.Begin); // The memory slab begins at the packet start
int msgSize = pvSrc.ReadUInt16();
Serial serial = pvSrc.ReadUInt32();
var vendor = World.FindMobile(serial);
if (vendor == null) return;
if (vendor.Deleted || !Utility.RangeCheck(vendor.Location, state.Mobile.Location, 10))
{
state.Send(new EndVendorSell(vendor));
return;
}
int count = pvSrc.ReadUInt16();
if (count < 100 && msgSize == (1 + 2 + 4 + 2 + (count * 6))) // Use the packet message size, not the buffer size
{
var sellList = new List<SellItemResponse>(count);
for (var i = 0; i < count; i++)
{
var item = World.FindItem(pvSrc.ReadUInt32());
int amount = pvSrc.ReadInt16();
if (item != null && amount > 0)
sellList.Add(new SellItemResponse(item, amount));
}
if (sellList.Count > 0 && vendor is IVendor v && v.OnSellItems(state.Mobile, sellList))
state.Send(new EndVendorSell(vendor));
}
}
Updates the codebase to the newest code paradigms and standards. This includes:
??
(null coalescing) instead of ternarythis
ArrayList
, HashTable
, and object[] states
with typed collections.out
variable declarationIn Progress:
PRs:
#1 - Updates code formatting, style, fixes various small bugs, and changes casts/type checks to use pattern matching
#3, #37- Updates out variables, adding items with optional parameters in ctor, and makes functions that take typeof variables use generics.
#7 - Fixes Dictionary uses throughout repo
#14 - More cleanup
#18 - Collapsing more null checks and removing overloading constructors
#31 - Fix comparables
#36 - Cleans up SpellTargeting
Lots of strings were not localized. Let's convert as many as we can!
The client vendor buy reply packet is sent whenever a player purchases an item from an NPC vendor. However to the client nothing appears to happen once you finish buying from the vendor. I've narrowed down the issue to a packet handling problem.
The VendorBuyReply
packet handler requires the message size in order to read the list of items requested to be purchased:
// PacketHandlers.cs#L500
pvSrc.Seek(1, SeekOrigin.Begin);
int msgSize = pvSrc.ReadUInt16();
var vendor = World.FindMobile(pvSrc.ReadUInt32());
var flag = pvSrc.ReadByte();
if (vendor == null)
return;
However at this point the message size has already been truncated by the main ProcessPacket
function, which slices the packet after the final position containing the Packet Id and Packet Length:
// PacketHandlers.cs#L350
var packet = seq.Slice(r.Position);
var memOwner = _memoryPool.Rent((int)packet.Length);
packet.CopyTo(memOwner.Memory.Span);
pump.QueueWork(ns, memOwner, handler.OnReceive);
The VendorBuyReply
packet handler expects to receive all the packet data, however it's offset, so the msg size and serial are instead read out of the buy list data and come out all garbled. The information about the packet size doesn't seem to get preserved anywhere in the PacketReader
to replace the ReadUInt16
call from what I could see.
I would submit a PR however with the new packet updates coming and this not being a simple change I figured it would be best to raise it here.
I'm using a temporary workaround in ProcessPacket
:
// PacketHandlers.cs#L350
if (packetId == 0x3B)
r.Seek(0, SeekOrigin.Begin);
Hey, in my tinkering with runuo 2.5 and 2.6 i noticed that if negative weight compounded beyond a certain limit it would default to max weight. I wanted to make a bag that would randomly generate with a weight from 1 to -150 and thus would allow an extra 100 ores (in that area). I got the bag to spawn off of an npc vendor but when i started bug checking the bag i ran into all kinds of default weight errors.
Things i noticed:
Stacking negitive weight bags with no other items would additionally subtract weight through the chain of bags until the player weight reached some sort of threshold and defaulted to max weight.
Having multiple items in a bag with negative weight subtracted as it should but the weight modifier could not keep up with alot of fast changes (bag sorting, pot use, so on) and defaulted to max weight.
Negative weight bags on pets with pack did nothing so far as i could see.
So i concluded that deffing a minimum negative weight would resolve most of the issues i was having the consequence i was going to use was not being able to pick items off of the ground if player weight fell below a minimum weight. Thus using it would require planning.
I searched around alot for similar errors but never really found a good solution.
The last thing i was working on was getting the player total weight and subtracting 200 if the weight exceeded the players carry capacity before stamina burn.
Ill post my scripts on runuo's git when i can. I figured that if your going to rework the entire arcitecture deffining minium weight and some negitive handeling would prevent alot of needless crashing.
Excuse by bad spelling.
The GetHashCode overrides that xor integer values are not actually a good idea. Not even sure if the values would be unique against the contents.
These should be replaced with prime number multiply-add.
ipLImiter
to ipLimiter
(capitalization)enabled
to enable
Argon2
vetReards
to vetRewards
Looks like targeting statics is broken. This might be related to changes I made in loading static files.
Tested the following:
Eliminate the readers and use Span extension methods instead.
Split layered items from stackable items since there are no countable equippable items.
Even an item like a throwable (BaseThrown on ServUO) doesn't have an actual "Amount".
Tools that have a UsesRemaining or amount-ish property do not use stackable Amount.
It looks like some legacy code still references the double value (converted from underlying integer value) for skills. This should be completely converted. The doubles are converted to ushort for the client under the hood, so all calculations/references should be changed to eliminate the doubles.
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
at Server.Items.BaseInstrument.GetPoisonLevel(BaseCreature bc) in C:\Users\Tony\Desktop\ModernUO-master\Projects\UOContent\Items\Skill Items\Musical Instruments\BaseInstrument.cs:line 240
at Server.Items.BaseInstrument.GetBaseDifficulty(Mobile targ) in C:\Users\Tony\Desktop\ModernUO-master\Projects\UOContent\Items\Skill Items\Musical Instruments\BaseInstrument.cs:line 270
at Server.Items.BaseInstrument.GetDifficultyFor(Mobile targ) in C:\Users\Tony\Desktop\ModernUO-master\Projects\UOContent\Items\Skill Items\Musical Instruments\BaseInstrument.cs:line 285
at Server.SkillHandlers.Peacemaking.InternalTarget.OnTarget(Mobile from, Object targeted) in C:\Users\Tony\Desktop\ModernUO-master\Projects\UOContent\Skills\Peacemaking.cs:line 159
at Server.Targeting.Target.Invoke(Mobile from, Object targeted) in C:\Users\Tony\Desktop\ModernUO-master\Projects\Server\Targeting\Target.cs:line 204
at Server.Network.PacketHandlers.TargetResponse(NetState state, PacketReader pvSrc) in C:\Users\Tony\Desktop\ModernUO-master\Projects\Server\Network\PacketHandlers.cs:line 1097
at Server.Network.MessagePumpService.DoWork() in C:\Users\Tony\Desktop\ModernUO-master\Projects\Server\Network\MessagePumpService.cs:line 51
at Server.Core.RunEventLoop(IMessagePumpService messagePumpService) in C:\Users\Tony\Desktop\ModernUO-master\Projects\Server\Main.cs:line 421
While it seems trivial, this low hanging fruit should be straight forward.
Books are 20-40 pages and each one has an array of 40 page objects with empty line arrays.
Optimize this to use a linked list or at least an array of nulls. Could also pull from a pool of page objects to lower allocations.
This will also optimize the packets being sent.
To distinguish ourselves from RunUO, we should have our own icon.
Using [vendorgen never ends. After a world save it finishes and is incomplete.
No crash.
Opportunities for improving the GetXInRange checks for high number of players/mobiles in a specific area. It looks like large shards are getting CPU lag spikes specifically due to this.
@jaedan identified some ways of optimizing this to reduce high CPU load.
Lux had a great idea that has already been implemented on other shards.
We should replace the type lists for crafting/loot/etc that use Activator.CreateInstance (Reflection) with a factory function using lambda expression. This can be inline or accessed via a static function from the object's class.
e.g. (int amount = 1) => new Gold(amount)
According to JB, HouseFoundation has several variables that are used in and out of locks, making the variables volatile. This should be redesigned/fixed, and if possible, with locks eliminated entirely.
Replace email log code to fix the following warnings:
`System.Net.Mail.SmtpClient' is obsolete: `SmtpClient and its network of types are poorly designed, we strongly recommend you use https://github.com/jstedfast/MailKit and https://github.com/jstedfast/MimeKit instead'
Update the housing system to use 3D regions instead of 2D. This will allow townhouse and other systems to easily integrate without causing region issues that would allow exploitation.
Using Activator.CreateInstance to generate loot is kind of sucky. Look into a better method, potentially using new T()
or factory methods?
The current configuration for travis will not work. We should set up a dockerized test environment.
Linting: https://www.jetbrains.com/resharper/download/index.html#section=commandline
Travis: https://travis-ci.community/t/net-core-3-0-preview/1936/6
Circle: https://dev.to/herocod3r/setup-a-ci-cd-pipeline-for-net-core-with-circleci-292d
Implement the client's fast walk stack.
Packet information here: POL Docs
We should have a welcoming website with the following:
I deleted the new mobile animation code. It needs to be put back for Stygian Abyss / Gargoyles (Flying).
Looks like there is a MessageHelper and it is contrived. Let's lean into it to reduce the size of referenced Mobile objects.
With the change to arrow body expression and shorthand properties, lots of constructors have values assigned which may get overridden by a parent or vice versa when they shouldn't.
Might need to introduce a general Item/Mobile init function.
All inheritance relying on NonGeneric IComparable/IComparer should be replaced with the generic where possible. Uses of generic object comparisons, if they exist, should also be replaced where possible.
Looks like Region takes Areas and breaks them down into non-overlapping rectangles.
We should just do this directly in BaseRegion so we are only storing one set.
This will make more sense after the BaseRegion Spawn code is removed entirely.
Using [signgen crashes the shard
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Server.Commands.SignParser.Parse(Mobile from) in Y:\Repositories\ModernUO\Projects\Scripts\Commands\SignParser.cs:line 25
at Server.Commands.SignParser.SignGen_OnCommand(CommandEventArgs c) in Y:\Repositories\ModernUO\Projects\Scripts\Commands\SignParser.cs:line 21
at Server.CommandSystem.Handle(Mobile from, String text, MessageType type) in Y:\Repositories\ModernUO\Projects\Server\Commands.cs:line 217
at Server.Mobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue) in Y:\Repositories\ModernUO\Projects\Server\Mobile.cs:line 4903
at Server.Mobiles.PlayerMobile.DoSpeech(String text, Int32[] keywords, MessageType type, Int32 hue) in Y:\Repositories\ModernUO\Projects\Scripts\Mobiles\PlayerMobile.cs:line 1999
at Server.Network.PacketHandlers.UnicodeSpeech(NetState state, PacketReader pvSrc) in Y:\Repositories\ModernUO\Projects\Server\Network\PacketHandlers.cs:line 1340
at Server.Network.MessagePump.DoWork() in Y:\Repositories\ModernUO\Projects\Server\Network\MessagePump.cs:line 58
at Server.Core.Main(String[] args) in Y:\Repositories\ModernUO\Projects\Server\Main.cs:line 482
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.