Freelancer Community Network
Reminder: Internet Explorer 6 or below are NOT supported.
HomeHome
ForumForum
WikiWiki
DownloadsDownloads
ForgeForge
Multiplayer Connection Tutorial
Collapse/Expand Random Image
Collapse/Expand Login
Username:

Password:

Remember me



Lost Password?

Register now!
Collapse/Expand Chat
Collapse/Expand Who's Online
69 user(s) are online (48 user(s) are browsing Forum)

Members: 1
Guests: 68

Andromeda, more...
Collapse/Expand Donations
Monthly costs: -30€
Income (ads): +5€
Donations (last month): +0€

Current balance: 55€
(last updated 04/2021)

Please make a donation if you want to help keeping The-Starport online:

Thanks!
Collapse/Expand Links
Collapse/Expand Advertisement
There are currently 33 users playing Freelancer on 36 servers.
September. 17, 2021

Browsing this Thread:   1 Anonymous Users



 Bottom   Previous Topic   Next Topic  Register To Post



[Clientside]Custom key commands
Just can't stay away
Joined:
2008/8/21 4:48
Group:
Registered Users
FLServer Admins
Trusted Speciality Developers
Senior Members
Posts: 454
Offline
The following code provides a means to override or extend the key commands in freelancer. In the example below I've added a USER_HUD to toggle the hud visibility.

In KeyMap.ini
Code:

[KeyCmd]
nickname = USER_HUD
ids_name = 1983 ; replace these with new ids 
ids_info = 3217 ; replace these with new ids
state = keydown
key = "L"

[KeyMap]
nickname = IDR_ALWAYS_PRESENT
key = USER_HUD


In keylist.ini
Code:

[key]
id = USER_HUD


And in the client side DLL
Code:

void __stdcall HkCb_HandleKeyCmd(int keycmd, int dunno)
{
 if (keycmd == 0x0000008d) // key index of USER_STEALTH which is renamed USER_HUD.
 {
      // do stuff here
 }
}

__declspec(naked) void HkCb_HandleKeyCmdNaked(void)
{
 __asm
 {
  push [esp+8] 
  push [esp+8]
  call HkCb_HandleKeyCmd

  sub esp, 80h
  push ebx
  mov ecx, 0x00576417
  jmp ecx
 }
}

Patch()
{
 // Patch keynames
 {
  char patch[] = "USER_HUD\x00\x00\x00\x00";
  WriteProcMem((char*)0x5E376C, &patch, 13);
 }

 // Patch keycmd processor
 {
  BYTE patch[] = { 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE1 }; // mov ecx HkCb_HandleKeyCmdNaked, jmp ecx
  DWORD *iAddr = (DWORD*)((char*)&patch + 1);
  *iAddr = reinterpret_cast<DWORD>((void*)HkCb_HandleKeyCmdNaked);
  WriteProcMem((char*)0x576410, &patch, 7); 
 }
}


With a patch a on the keyname list it should be possible to add any number of new key command but in the above example I've just renamed an existing but unused command (USER_STEALTH).

EDIT: it turns out that there are heaps of unused commands, i've added 8 new commands so far.

Open in new window

Posted on: 2010/9/19 4:03
Top
Re: [Clientside]Custom key commands
Starport Admin
Joined:
2009/2/21 21:42
Group:
Webmasters
Registered Users
Posts: 3520
Offline
Very nice find

Posted on: 2010/9/19 4:40
"Cynicism is not realistic and tough. It's unrealistic and kind of cowardly because it means you don't have to try."
-Peggy Noonan
Top
Re: [Clientside]Custom key commands
Starport Admin
Joined:
2008/2/26 20:36
From Germany
Group:
Webmasters
Registered Users
Posts: 1791
Offline
You may also be interested in this:

Code:
uint iState = *(int*)0x067C290; // iState == 0 -> keyup | iState == 1 -> keydown


There are indeed a lot of unused keys, btw. here is an enum:

Code:

enum INPUT_COMMANDS
{
USER_NONE,
USER_KEY,
USER_CHAR,
USER_BUTTON,
USER_WHEEL,
USER_MOVE,
USER_BUTTON0,
USER_BUTTON1,
USER_BUTTON2,
USER_BUTTON3,
USER_BUTTON4,
USER_BUTTON5,
USER_BUTTON6,
USER_BUTTON7,
USER_EVENTS,
USER_CANCEL,
USER_STACKABLE_CANCEL,
USER_ENTER,
USER_NO,
USER_YES,
USER_PAUSE,
USER_RESET,
USER_SAVE_GAME,
USER_FULLSCREEN,
USER_USE_ITEM,
USER_ACTIVATE_ITEM,
USER_NEXT_ITEM,
USER_PREV_ITEM,
USER_SET_TARGET,
USER_NEXT_TARGET,
USER_PREV_TARGET,
USER_NEXT_WEAPON_SUBTARGET,
USER_PREV_WEAPON_SUBTARGET,
USER_NEXT_SUBTARGET,
USER_PREV_SUBTARGET,
USER_CLEAR_TARGET,
USER_NEXT_ENEMY,
USER_PREV_ENEMY,
USER_CLOSEST_ENEMY,
USER_ZOOM_IN,
USER_ZOOM_OUT,
USER_ZOOM_TOGGLE,
USER_X_ROTATE,
USER_X_UNROTATE,
USER_Y_ROTATE,
USER_Y_UNROTATE,
USER_Z_ROTATE,
USER_Z_UNROTATE,
USER_VIEW_RESET,
USER_COCKPIT_CAMERA_MODE,
USER_LOOK_ROTATE_CAMERA_LEFT,
USER_LOOK_ROTATE_CAMERA_RIGHT,
USER_LOOK_ROTATE_CAMERA_UP,
USER_LOOK_ROTATE_CAMERA_DOWN,
USER_LOOK_ROTATE_CAMERA_RESET,
USER_CHASE_CAMERA_MODE,
USER_REARVIEW_CAMERA_MODE,
USER_REARVIEW_CAMERA_MODE_OFF,
USER_AFTERBURN,
USER_AFTERBURN_OFF,
USER_AFTERBURN_ON,
USER_TOGGLE_AUTO_AVOIDANCE,
USER_TOGGLE_AUTO_LEVEL,
USER_TOGGLE_LEVEL_CAMERA,
USER_WARP,
USER_ENGINE_TOGGLE,
USER_SET_THROTTLE,
USER_INC_THROTTLE,
USER_DEC_THROTTLE,
USER_CRUISE,
USER_THROTTLE_0,
USER_THROTTLE_10,
USER_THROTTLE_20,
USER_THROTTLE_25,
USER_THROTTLE_30,
USER_THROTTLE_40,
USER_THROTTLE_50,
USER_THROTTLE_60,
USER_THROTTLE_70,
USER_THROTTLE_75,
USER_THROTTLE_80,
USER_THROTTLE_90,
USER_THROTTLE_100,
USER_RADAR,
USER_CONTACT_LIST,
USER_RADAR_ZOOM,
USER_SWITCH_TO_PLAYER_SHIP,
USER_SWITCH_TO_WEAPON_LIST,
USER_SWITCH_TO_TARGET,
USER_FORMATION_LIST,
USER_RADAR_ZOOM_IN,
USER_RADAR_ZOOM_OUT,
USER_RADIO,
USER_CHAT,
USER_STATUS,
USER_TARGET,
USER_STATUS_MODE,
USER_TOGGLE_MAINFRAME,
USER_NN,
USER_NAV_MAP,
USER_NAVMAP,
USER_PLAYER_STATS,
USER_INVENTORY,
USER_STORY_STAR,
USER_CHAT_WINDOW,
USER_GROUP_WINDOW,
USER_HELP,
USER_INVENTORY_CLOSE,
NN_TOGGLE_OPEN,
USER_MINIMIZE_HUD,
USER_DISPLAY_LAST_OBJECTIVE,
USER_COLLECT_LOOT,
USER_ACTIONS,
USER_MANEUVER,
USER_SET_MANEUVER_DIRECTION,
USER_MANEUVER_WINDOW,
USER_MANEUVER_TRAIL,
USER_MANEUVER_AFTERBURNER,
USER_MANEUVER_EVADE,
USER_MANEUVER_ENGINEKILL,
USER_MANEUVER_BRAKE_REVERSE,
USER_MANEUVER_DOCK,
USER_MANEUVER_GOTO,
USER_MANEUVER_FACE,
USER_MANEUVER_CRUISE,
USER_MANEUVER_TRADE_LANE,
USER_MANEUVER_DRASTIC_EVADE,
USER_MANEUVER_FORMATION,
USER_MANEUVER_STRAFE,
USER_MANEUVER_TRAIL_CLOSER,
USER_MANEUVER_TRAIL_FARTHER,
USER_MANEUVER_CORKSCREW_EVADE,
USER_MANEUVER_SLIDE_EVADE,
USER_MANEUVER_SLIDE_EVADE_LEFT,
USER_MANEUVER_SLIDE_EVADE_RIGHT,
USER_MANEUVER_SLIDE_EVADE_UP,
USER_MANEUVER_SLIDE_EVADE_DOWN,
USER_ACTIVATE_MANEUVER,
USER_SCAN_CARGO,
USER_TRACTOR_BEAM,
USER_JAMMER,
USER_STEALTH,
USER_CLOAK,
USER_REPAIR_HEALTH,
USER_REPAIR_SHIELD,
USER_WEAPON_GROUP1,
USER_WEAPON_GROUP2,
USER_WEAPON_GROUP3,
USER_WEAPON_GROUP4,
USER_WEAPON_GROUP5,
USER_WEAPON_GROUP6,
USER_TOGGLE_WEAPON1,
USER_TOGGLE_WEAPON2,
USER_TOGGLE_WEAPON3,
USER_TOGGLE_WEAPON4,
USER_TOGGLE_WEAPON5,
USER_TOGGLE_WEAPON6,
USER_TOGGLE_WEAPON7,
USER_TOGGLE_WEAPON8,
USER_TOGGLE_WEAPON9,
USER_TOGGLE_WEAPON10,
USER_FIRE_WEAPON1,
USER_FIRE_WEAPON2,
USER_FIRE_WEAPON3,
USER_FIRE_WEAPON4,
USER_FIRE_WEAPON5,
USER_FIRE_WEAPON6,
USER_FIRE_WEAPON7,
USER_FIRE_WEAPON8,
USER_FIRE_WEAPON9,
USER_FIRE_WEAPON10,
USER_FIRE_WEAPON_GROUP1,
USER_FIRE_WEAPON_GROUP2,
USER_FIRE_WEAPON_GROUP3,
USER_FIRE_WEAPON_GROUP4,
USER_FIRE_WEAPON_GROUP5,
USER_FIRE_WEAPON_GROUP6,
USER_ASSIGN_WEAPON_GROUP1,
USER_ASSIGN_WEAPON_GROUP2,
USER_ASSIGN_WEAPON_GROUP3,
USER_ASSIGN_WEAPON_GROUP4,
USER_ASSIGN_WEAPON_GROUP5,
USER_ASSIGN_WEAPON_GROUP6,
USER_REMAPPABLE_LEFT,
USER_REMAPPABLE_RIGHT,
USER_REMAPPABLE_UP,
USER_REMAPPABLE_DOWN,
USER_FIRE_FORWARD,
USER_LAUNCH_MISSILES,
USER_LAUNCH_MINES,
USER_LAUNCH_COUNTERMEASURES,
USER_AUTO_TURRET,
USER_LAUNCH_TORPEDOS,
USER_LAUNCH_CRUISE_DISRUPTORS,
USER_TURN,
USER_NEXT_OBJECT,
USER_PREV_OBJECT,
USER_EXIT_GAME,
USER_MANEUVER_FREE_FLIGHT,
USER_FIRE_WEAPONS,
USER_TURN_SHIP,
USER_GROUP_INVITE,
USER_TRADE_REQUEST,
USER_SCREEN_SHOT
};


Posted on: 2010/9/19 23:50
aka chaosgrid
http://www.freelancerserver.de
https://www.moddb.com/mods/fwtow
Top
Re: [Clientside]Custom key commands
Home away from home
Joined:
2009/8/16 2:58
From Qld, Aus.
Group:
Registered Users
FLServer Admins
Trusted Speciality Developers
Senior Members
Posts: 1997
Offline
The keys that aren't used are here.

Posted on: 2010/9/20 3:27
Top
Re: [Clientside]Custom key commands
Just can't stay away
Joined:
2008/5/9 17:27
Group:
Registered Users
FLServer Admins
Trusted Speciality Developers
Senior Members
Posts: 246
Offline
Checking if the chat input window is open:

Code:

typedef void* (*_GetObjByStr)(char*);
_GetObjByStr GetObjByStr = (_GetObjByStr)0x59DA10;


Code:

void __stdcall HkCb_HandleKeyCmd(int keycmd, int dunno)
{
    ...

    void* Obj = GetObjByStr("CTID");
    byte byIsChatOpen;
    ReadProcMem((char*)Obj+1337, &byIsChatOpen, 1);
    if(byIsChatOpen)
       return;

    ...

Posted on: 2010/9/20 17:08
Top
Re: [Clientside]Custom key commands
Home away from home
Joined:
2009/8/16 2:58
From Qld, Aus.
Group:
Registered Users
FLServer Admins
Trusted Speciality Developers
Senior Members
Posts: 1997
Offline
I don't understand all this use of ReadProcMem. Plugins are loaded into the address space of the process, so there's no need for it. What's wrong with just:

Code:
struct SomeObjectType
{
  byte todo[0x1337];
  bool bIsOpen;
  // byte more_todo[];
};

typedef SomeObjectType* (*_GetObjByStr)(const char*);

SomeObjectType* obj = _GetObjByStr("CTID");
if (obj->bIsOpen)
  return;

Posted on: 2010/9/21 2:10
Top
Re: [Clientside]Custom key commands
Just can't stay away
Joined:
2008/8/21 4:48
Group:
Registered Users
FLServer Admins
Trusted Speciality Developers
Senior Members
Posts: 454
Offline
An update to the code so that a keypress that is processed by a custom command will not be printed into the chat box, if the chat box is open.

Code:

bool __stdcall HkCb_HandleKeyCmd(int keycmd, int dunno)
{
    switch (keycmd)
    case blah:
       return true; // if you process it
     default:
        return false; // if you don't
}  

__declspec(naked) void HkCb_HandleKeyCmdNaked(void)
{
__asm
{
push [esp+8] 
push [esp+8]
call HkCb_HandleKeyCmd
test al, al
jz   cmd_not_processed
ret

cmd_not_processed:
sub esp, 80h
push ebx
mov ecx, 0x00576417
jmp ecx

}
}


I guess there's no reason to have this in the private section. I'm not sure why I put it here so if a site admin wants to move it then do so please....

Posted on: 2010/9/25 22:31
Top
Re: [Clientside]Custom key commands

Joined:
2016/3/29 21:54
From England
Group:
Registered Users
Trusted Speciality Developers
Posts: 43
Offline
A bit of a grave dig, but I was wondering if anybody knows the location of the function for handling the release of input.

From what I can tell, any key defined inside of keymap.ini with a state of "keydown, keyup" will only fire an event in the above function for the initial keydown state. This is great for intercepting calls, but sometimes I want to supress the cancelation.

Posted on: 8/27 13:18
Way too ambitious for his own good.
Top