Current ToDo

The latest version of the UOAI library and all directly related information can be found in this forum.

Current ToDo

Postby Artaxerxes on Fri Nov 21, 2008 9:35 pm

updated: September 25 2009

The latest version of UOAI and the changelist are now maintained in another thread.

In this thread I'll stick to the todo list.

ToDo:

This todo will be updated regulary, the order of things might change, some new things might be added now and then, some ideas might get removed in time...

  • Next v0.4 version
    • fixing the enumerators: foreach(UOItem curitem in Player.Backpack) {curitem.Drag...} would fail with the current version cause the contents of the backpack is not allowed to change while enumerating it... so you need to dump the contents into a list or array and then enumerate that array. This is not really a bug, try enumerating some datastructures in .NET and removing the item you currently got from the enumerator; several of the datastructures will throw an exception. The only solution for this is the trick of dumping everything into a second list and enumerating from there; so the only fix i can provide is to do this in the background and transparantly return an enumerator for that list instead of one for the original datastructure.
    • Finditem calls are relatively slow, cause they perform linear searches. This basically requires rebuilding the event system and allowing for synchronized packet handling. Most changes are located in the injected UOClientDll.dll and were already done while working on the next .NET library; so it makes sense to rewrite the COM library to start using this new version of the injected dll.
    • By switching to this new UOClientDll.dll i would also be able to join the >=v7.0.0.0 and <v7.0.0.0 version. (it would work for now, but still the callibration part requires some major updates)
    • Since i'm switching to another dll, i might also look at switching to another dll-injection method, which will be required to compile a 64bit version of the COM library; probably i'll switch from windows hooks to the code-injection/setThreadContext method, unless someone knows a better method? (thing that annoys me with code-injection is that i have to allocate a whole memory-page on the client, of which i will only use a few bytes to perform the loadlibrary call and restore the original EIP)
    • Self-Registration functionality should finally be implemented correctly, to allow for easier distribution.
    • Add .loggedin checks. A lot of methods can not be executed succesfully on clients that are not logged in... currenlty however no .loggedin checks are present.

  • UOAI v0.5.0
    • Finish an include/header-file for C/C++ developers with some usage-info.
    • Website and documentation require major updates. At least a bug-reporting system, that will allow you to specifiy bugs specific to certain client- and UOAI-versions; and a versioning system, allowing seperation of a stable UOAI version vs experimental updates, should be available before moving on to UOAI v0.5.
    • Access to the clients main window handle. (Maybe also a client.BringToTop and a client.TitelBar member...)
    • Client.Close() function?
    • ShowMessage should allow specifying the color + a function to display speech above a mobile or item should be (re)added.
    • Some way to get hold of an attacker/killer?
    • Add access to the game/loginserver host/port.
    • Item.MultiType for multi-items. I originally planned to get all multi-components accessible through Item.Contents first (for items with Item.IsMulti=true)... but, even though i have access to those component-items from the multi-item, they are not in the main-itemlist, which complicates validation and synchronization-locking from UOAI. The changes required are therefore more complicated and will be delayed until a later v0.5 version. Instead, i'll add this .MultiType variable, which should allow lookup of the multi in the client's multi-mul-file.
    • Lookup-function for localized messages.
    • DropInto should allow a user to specify coordinates within a container.
    • statusinfo: Mobile.Race, Mobile.TitchingPoints should be added
    • Consider adding a UOClient.onNewItemProperties event.
    • Add PacketQueue.onQueue event. (actually this is kindof useless, given that packetqueues are to be used for asynchronous packet access, where as the packevents take care of synchronous packetevents.. there is little advantage to implementing a packetqueue.onqueue event if the .onPacketReceive/Sent events are already present.)
    • Add packetbased UOMobile.Follow() and .StopFollowing() functions.
    • Vendor buy/sell handling.
    • onSecureTrade event.
    • Add UOMobileList and implement UOClient.Party as such a UOMobileList. (party-info calibrations are already present, so this shouldn’t take too long).
    • Property/name parsing : removing the html formatting from .Name and .Properties and creating an enumerable list of properties, rather than one string with all of them.
    • Fix some problems when using FindClientByPID feature.
    • Changes to .Login : .Login(server,port,username,password) will return a "UOLoginObject" (or other name). That UOLoginObject then allows you to step through the login-procedure. A UOLoginObject.serverlist contains a list of servers. You will be able to choose your server using "UOLoginObject.serverlist(serverindex).Select()". This will then update the login-object. Its UOLoginObject.characterlist will contain a list of all characters, and again .Select() allows you to select one. Features to get the ping to a specific server, or to create/delete characters might be added too.
    • Multis. Was planned for 0.4 version, but now moved down. I will first add a .MultiType (see above). Later on Multi-components will be made accessible through UOItem.contents for multi-items (check with UOItem.isMulti?). This was already added, but is not functioning properly.
  • Some future version (= either a lot of work, or not completely clear yet how i will implement this) :
    • GumpEvents (only .onClose is implemented right now). : problem is that different gumps are handled differently… I’m thinking about adding different interfaces for different types of gumps, allowing events to be implemented based on the gumptype.
    • Context Menu Handling. (still a lot of work to do on this one)
    • Try to move UOAI to a Single-Threaded Appartment, which should result in easier usage from windows forms applications.
    • I will add a UOClient.UOMacros object, similar to the one available in the wrapper, with enumerations for all types of parameters.
    • Mapfile-access, Anim.mul access
    • Custom Gumps? (creation of custom UOGump objects that can be displayed on the client)
    • Long distance pathfinder
    • Access to the clients window titlebar?
    • Runuo protocol extensions.
    • Mobile.followers-list? If possible. Currently you could just loop all mobiles and check if they are renameable.
    • Add support for requested client version(s). (adding support for older client versions is a major task, and therefore you should not expect that to be done any time soon)

Greetz,
Artaxerxes
Artaxerxes
Site Admin
 
Posts: 530
Joined: Tue Nov 18, 2008 9:51 pm

Re: Current ToDo

Postby arul on Sat Nov 22, 2008 4:12 am

Regarding the UO Files, UltimaSDK can work with nearly all kinds of client files.
Check my latest check-in at Codeplex: http://www.codeplex.com/ultimasdk/Sourc ... mmits.aspx

I could rewrite them in C, but I'm afraid that my COM-in-C is little rusty :)

:geek:
arul
Pro
 
Posts: 107
Joined: Thu Nov 20, 2008 2:03 am
Location: Prague

Re: Current ToDo

Postby Artaxerxes on Sat Nov 22, 2008 12:38 pm

I know about the Ultima SDK, a version of it is on my pc.

Also, I wrote some basic UO-file parsers before, think I might reuse them.

I will see if I can write a quick introduction into how you can write COM object with my code, if I find the time. But for today i'm gonna start working through the first items in the todo-list here.
Artaxerxes
Site Admin
 
Posts: 530
Joined: Tue Nov 18, 2008 9:51 pm

Re: Current ToDo

Postby arul on Sun Nov 23, 2008 8:31 am

Artaxerxes wrote:I know about the Ultima SDK, a version of it is on my pc.

Also, I wrote some basic UO-file parsers before, think I might reuse them.

I will see if I can write a quick introduction into how you can write COM object with my code, if I find the time. But for today i'm gonna start working through the first items in the todo-list here.


Okays, can't wait to download a new version :)
arul
Pro
 
Posts: 107
Joined: Thu Nov 20, 2008 2:03 am
Location: Prague

Re: Current ToDo

Postby Artaxerxes on Sun Nov 23, 2008 11:15 am

Is gonna take some time though, I fixed the signed/unsigned problem and I'm currently working on event based code. But since that's already a lot of work, so I think the File-parsers will not be present yet today.

I need some suggestions on how the event-based code should look, cause I can see different options: The packet-events are trivial, just put an onPacketSend and on onPacketRecv event on the UOClient object, but I also am triggering events after parsing those packets.
Now I can f.e. implement a UOItem_onMove() event OR a UOClient_onItemMove(UOItem) event. In C# the difference is mostly not important, since you can provide delegates for each event, but in languages like visual basic it is a huge difference, cause you typically don't dynamically assign event-handlers there. Since your UOClient object is typically one object, static event handlers work fine, but for UOItems thats a different story. But then again, maybe I shouldnt try to push vb6 and vbScript support that far.
Another thing: I could also provide async events through a queue that watches for specific packets of your choice. So I would provide a UOClient.CreatePacketEventQueue() method which returns a new UOEventQueue object, then you can set which packets to filter for this queue: UOEventQueue.AddPacket(packetnumber). My code will then add the packets with the specified packetnumbers to your queue when they arrive (where you can use UOEventQueue.hasPacket and UOEventQueue.dequeue() and UOEventQueue.Clear() and UOEventQueue.WaitForEvent() to access them). So you still get the events, but in an async way. There are advantages to that, f.e. a minerbot would typically do something like:
Code: Select all
MiningEventqueue.AddPacket(CLILOC_PACKET_NUMBER)
MiningEventQueue.Clear()
DoMine()
MiningEventQueue.WaitForEvent()
' check here which cliloc the packetevent has: is it one of the miningresponses? -> mining success/failure, otherwise wait for the next cliloc event

With actualy (synchronized) COM events, you would not be able to program that in a serial way, since your code would be jumping in between event-handlers.
Also I could add more than just packet-events to such a queue. F.e. the pathfinder i intend to implement might provide information back to the user through events: onArrive, onPathfindFailure, ... Since I will allow large distances, pathfinding is done on the map-files, while in-game some paths might be blocked that are not on the map... since there is no way of knowing that until the path is being walked, it is necessary to return pathfindfailure somehow.

Currently I'm going with event-based code like this (what i got up to now):
UOAI_onNewClient(UOClient newclient)
UOClient_onExit
UOClient_onPacketRecv(BYTE [] packet,int packetlength)
UOClient_onPacketSend(BYTE [] packet,int packetlength)
UOClient_onNewItem(UOItem newitem)
UOMobile_onDelete()
'UOMobile_onInvalidate()
UOMobile_beforeUpdate() 'gives you a chance to store previous info, f.e. a tamer-script following an tameable mobile, might not just wont to know where the tameable moved to in an onMove, but might want to know the exact path
UOMobile_onUpdate()

...
Artaxerxes
Site Admin
 
Posts: 530
Joined: Tue Nov 18, 2008 9:51 pm

Re: Current ToDo

Postby arul on Sun Nov 23, 2008 4:15 pm

Artaxerxes wrote:Is gonna take some time though, I fixed the signed/unsigned problem and I'm currently working on event based code. But since that's already a lot of work, so I think the File-parsers will not be present yet today.

I need some suggestions on how the event-based code should look, cause I can see different options: The packet-events are trivial, just put an onPacketSend and on onPacketRecv event on the UOClient object, but I also am triggering events after parsing those packets.
Now I can f.e. implement a UOItem_onMove() event OR a UOClient_onItemMove(UOItem) event. In C# the difference is mostly not important, since you can provide delegates for each event, but in languages like visual basic it is a huge difference, cause you typically don't dynamically assign event-handlers there. Since your UOClient object is typically one object, static event handlers work fine, but for UOItems thats a different story. But then again, maybe I shouldnt try to push vb6 and vbScript support that far.


The 'AddressOf someProc' can't be used? Sorry, never been into VB so I might be alittle off, but C# delegates are marshalled as function pointers, which is the same value given by the AddressOf operator? For compatibility with VB-ish languages the function prototypes for such events could be declared as: UOItem_onMove(UOItem *pThis ... );
This way those events could be used both static/instance-wide, which kinda violates OOP, but who cares. :twisted:

Artaxerxes wrote:Another thing: I could also provide async events through a queue that watches for specific packets of your choice. So I would provide a UOClient.CreatePacketEventQueue() method which returns a new UOEventQueue object, then you can set which packets to filter for this queue: UOEventQueue.AddPacket(packetnumber). My code will then add the packets with the specified packetnumbers to your queue when they arrive (where you can use UOEventQueue.hasPacket and UOEventQueue.dequeue() and UOEventQueue.Clear() and UOEventQueue.WaitForEvent() to access them). So you still get the events, but in an async way. There are advantages to that, f.e. a minerbot would typically do something like:
Code: Select all
MiningEventqueue.AddPacket(CLILOC_PACKET_NUMBER)
MiningEventQueue.Clear()
DoMine()
MiningEventQueue.WaitForEvent()
' check here which cliloc the packetevent has: is it one of the miningresponses? -> mining success/failure, otherwise wait for the next cliloc event

With actualy (synchronized) COM events, you would not be able to program that in a serial way, since your code would be jumping in between event-handlers.
Also I could add more than just packet-events to such a queue. F.e. the pathfinder i intend to implement might provide information back to the user through events: onArrive, onPathfindFailure, ... Since I will allow large distances, pathfinding is done on the map-files, while in-game some paths might be blocked that are not on the map... since there is no way of knowing that until the path is being walked, it is necessary to return pathfindfailure somehow.


Neat feature, sadly I can't be of much help here as I'm not familiar with the COM+ event model :/
arul
Pro
 
Posts: 107
Joined: Thu Nov 20, 2008 2:03 am
Location: Prague

Re: Current ToDo

Postby Artaxerxes on Sun Nov 23, 2008 10:31 pm

A temporary version, supporting some events, is attached to this post. It should fix most of the unsigned/signed problems, and it should already trigger the following events (other events are in the typelibrary, but theres no code triggering them yet):

UOAI.onClientStart(UOClient newclient)
UOAI.onClientExit(UOClient invalidclient)

UOClient.onPacketReceive(Byte[] packet, int packetsize)
UOClient.onPacketSend(Byte[] packet, int packetsize)
UOClient.onExit()
UOClient.onNewItem(UOItem newitem)
UOClient.onNewMobile(UOMobile newmobile)
UOClient.onKeyDown(int virtualkeycode)
UOClient.onKeyUp(int virtualkeycode)

Events already listed in the object browser will be implemented next.
(+ 2 new ones: UOClient.beforePacketSend() and .beforePacketReceive(), which allow you to dump the packets... so they will never be send/received by the client... that allows the implementation of packetfilters. Things like filtering light-levels and season-changes is always interesting...)

arul wrote:The 'AddressOf someProc' can't be used? Sorry, never been into VB so I might be alittle off, but C# delegates are marshalled as function pointers, which is the same value given by the AddressOf operator? For compatibility with VB-ish languages the function prototypes for such events could be declared as: UOItem_onMove(UOItem *pThis ... );

Apparantly you're right, with 'AddHandler' and 'AddressOf' you can also dynamically add the eventhandlers in vb, I didnt know about 'AddHandler' up to today though :).

arul wrote:Neat feature, sadly I can't be of much help here as I'm not familiar with the COM+ event model :/

A good place to start, would be the COM in plain C guides on codeproject.com. It's not the best around, but I found it very usefull when I was first learning about COM in C. It's a lot to read though, so it might be easier to wait until I write some info on the specifics of my code. ;-).

Greetz,
Artaxerxes
Artaxerxes
Site Admin
 
Posts: 530
Joined: Tue Nov 18, 2008 9:51 pm

Re: Current ToDo

Postby arul on Mon Nov 24, 2008 12:04 am

Tried subscribing to all the events in the list, none of them was triggered once though :)

(... think I pressed the wrong button and instead of replying I somehow editted your post ... srry about that, Artaxerxes)
arul
Pro
 
Posts: 107
Joined: Thu Nov 20, 2008 2:03 am
Location: Prague

Re: Current ToDo

Postby Artaxerxes on Mon Nov 24, 2008 12:13 am

arul wrote:Tried subscribing to all the events in the list, none of them was triggered once though

Can you give me more details on what you tested up to now? Cause it the events seem to get triggered fine here...
Artaxerxes
Site Admin
 
Posts: 530
Joined: Tue Nov 18, 2008 9:51 pm

Re: Current ToDo

Postby arul on Mon Nov 24, 2008 12:17 am

Artaxerxes wrote:Can you give me more details on what you tested up to now? Cause it the events seem to get triggered fine here...


I simply subscribed to all event from your list and watched the output. There was no output at all :/

Didn't you attach an older version of the files, I peeked at the source and there's a lot of event-related stuff commented, like:

Code: Select all
   else if(uMsg==onreceivemessage)
   {
      //curpacket=(BYTE)wParam;
      //packetoffset=(unsigned int)lParam;
      //packetsize=getpacketsize((UOClient *)GetWindowLong(hwnd,GWL_USERDATA),packetoffset);
      
      onclient=(UOClient *)GetWindowLong(hwnd,GWL_USERDATA);
      
//      queue_packetevent(onclient,(BYTE)wParam,(unsigned int)lParam,FALSE);
      
      //debugprintf("received packet:\tpacket %x (size %u)\n",(BYTE)wParam,getpacketsize((UOClient *)GetWindowLong(hwnd,GWL_USERDATA),(unsigned int)lParam));

      remotefree(onclient->IPChwnd,(unsigned int)lParam);

      return 1;
   }
   else if(uMsg==onsentmessage)
   {
      //curpacket=(BYTE)wParam;
      //packetoffset=(unsigned int)lParam;
      //packetsize=getpacketsize((UOClient *)GetWindowLong(hwnd,GWL_USERDATA),packetoffset);

      //debugprintf("sent packet:\t\tpacket %x (size %u)\n",curpacket,packetsize);
      onclient=(UOClient *)GetWindowLong(hwnd,GWL_USERDATA);

      //queue_packetevent(onclient,(BYTE)wParam,(unsigned int)lParam,TRUE);

      //debugprintf("sent packet:\tpacket %x (size %u)\n",(BYTE)wParam,getpacketsize((UOClient *)GetWindowLong(hwnd,GWL_USERDATA),(unsigned int)lParam));
      
      remotefree(onclient->IPChwnd,(unsigned int)lParam);

      return 1;
   }
   else if(uMsg==onkeydownmessage)
   {
      //debugprintf("key down:\t\tvirtual key code %u\n",wParam);
      return 1;
   }
   else if(uMsg==onkeyupmessage)
   {
      //debugprintf("key up:\t\tvirtual key code %u\n",wParam);

      //queue_hotkeyevent((UOClient *)GetWindowLong(hwnd,GWL_USERDATA),(unsigned int)wParam);

      return 1;
   }
arul
Pro
 
Posts: 107
Joined: Thu Nov 20, 2008 2:03 am
Location: Prague

Next

Return to UOAI Developers Forum

Who is online

Users browsing this forum: No registered users and 1 guest

cron