Initial showing of the bot window
This commit is contained in:
parent
7be649b56b
commit
45ded91030
@ -69,7 +69,6 @@ add_library(ISXMr SHARED ${SOURCE_DIR}/ISXMr.cpp
|
|||||||
src/isxeq2/Actor.cpp
|
src/isxeq2/Actor.cpp
|
||||||
src/isxeq2/Actor.h
|
src/isxeq2/Actor.h
|
||||||
src/isxeq2/LSObject.h
|
src/isxeq2/LSObject.h
|
||||||
src/WriteUIFileToDisk.cpp
|
|
||||||
src/isxeq2/Point3f.h
|
src/isxeq2/Point3f.h
|
||||||
src/isxeq2/Ability.cpp
|
src/isxeq2/Ability.cpp
|
||||||
src/isxeq2/Ability.h
|
src/isxeq2/Ability.h
|
||||||
@ -78,12 +77,12 @@ add_library(ISXMr SHARED ${SOURCE_DIR}/ISXMr.cpp
|
|||||||
src/isxeq2/CharacterClass.h
|
src/isxeq2/CharacterClass.h
|
||||||
src/isxeq2/AbilityEffect.h
|
src/isxeq2/AbilityEffect.h
|
||||||
src/Logger.h
|
src/Logger.h
|
||||||
src/Commands/ExecutableCommand.h
|
src/Tasks/ExecutableTask.h
|
||||||
src/Commands/ExportCommand.cpp
|
src/Tasks/ExportAbilitiesTask.cpp
|
||||||
src/Commands/ExportCommand.h
|
src/Tasks/ExportAbilitiesTask.h
|
||||||
src/isxeq2/ExtensionTLOs.h
|
src/isxeq2/ExtensionTLOs.h
|
||||||
src/Commands/CommandExecutor.cpp
|
src/Tasks/TaskExecutor.cpp
|
||||||
src/Commands/CommandExecutor.h
|
src/Tasks/TaskExecutor.h
|
||||||
src/BotSettings/ExportedAbility.h
|
src/BotSettings/ExportedAbility.h
|
||||||
includes/argh/argh.h
|
includes/argh/argh.h
|
||||||
src/isxeq2/EQ2.h
|
src/isxeq2/EQ2.h
|
||||||
@ -94,6 +93,10 @@ add_library(ISXMr SHARED ${SOURCE_DIR}/ISXMr.cpp
|
|||||||
src/Api/MrBotApi.h
|
src/Api/MrBotApi.h
|
||||||
includes/json_struct/json_struct.h
|
includes/json_struct/json_struct.h
|
||||||
includes/json_struct/json_struct_diff.h
|
includes/json_struct/json_struct_diff.h
|
||||||
|
src/Tasks/BotTask.cpp
|
||||||
|
src/Tasks/BotTask.h
|
||||||
|
src/ScopedEnumBitwiseOperators.h
|
||||||
|
lgui2/UpdateUIPackageFile.h
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (WIN32)
|
IF (WIN32)
|
||||||
|
|||||||
687
lgui2/bot_cast_stack.json
Normal file
687
lgui2/bot_cast_stack.json
Normal file
@ -0,0 +1,687 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://www.lavishsoft.com/schema/lgui2Package.json",
|
||||||
|
"skin": "MRSkin",
|
||||||
|
"templates": {
|
||||||
|
"settings.abilityListEntry": {
|
||||||
|
"jsonTemplate": "listboxitem",
|
||||||
|
"padding": 2,
|
||||||
|
"content": {
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"-contentContainer": {
|
||||||
|
"jsonTemplate": "listbox.contentContainerFitWidth"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"textBinding": {
|
||||||
|
"pullFormat": "${_CONTEXTITEMDATA_.Get[name]}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings.castStack": {
|
||||||
|
"orientation": "vertical",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "panel",
|
||||||
|
"visibility": "hidden",
|
||||||
|
"name": "CastStackController.events"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"heightFactor": 0.9,
|
||||||
|
"widthFactor": 1,
|
||||||
|
"horizontalAlignment": "left",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"widthFactor": 0.3,
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "Ability List",
|
||||||
|
"widthFactor": 1,
|
||||||
|
"horizontalAlignment": "left"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "listbox",
|
||||||
|
"name": "abilityList",
|
||||||
|
"heightFactor": 0.9,
|
||||||
|
"itemsBinding": {
|
||||||
|
"pullFormat": "${CastStackController.abilityListItems}",
|
||||||
|
"pullOnce": true
|
||||||
|
},
|
||||||
|
"itemViewGenerators": {
|
||||||
|
"default": {
|
||||||
|
"type": "template",
|
||||||
|
"template": "settings.abilityListEntry"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selectedItemBinding": {
|
||||||
|
"pullFormat": "${CastStackController.currentSelectedAvailableAbilityIndex}",
|
||||||
|
"pushFormat": [
|
||||||
|
"CastStackController:SetCurrentAbility[\"",
|
||||||
|
"\"]"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"-contentContainer": {
|
||||||
|
"jsonTemplate": "listbox.contentContainerFitWidth"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"name": "castStack.addAbility",
|
||||||
|
"content": "Add Ability",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"eventHandlers": {
|
||||||
|
"onRelease": [
|
||||||
|
"method",
|
||||||
|
"CastStackController",
|
||||||
|
"AddAbility"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"widthFactor": 0.3,
|
||||||
|
"heightFactor": 1,
|
||||||
|
"verticalAlignment": "top",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"padding": [
|
||||||
|
0,
|
||||||
|
16,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "Type",
|
||||||
|
"width": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "combobox",
|
||||||
|
"name": "castStack.ability.type",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"items": [
|
||||||
|
"Combat",
|
||||||
|
"CA",
|
||||||
|
"NamedCA",
|
||||||
|
"Heal",
|
||||||
|
"PowerHeal",
|
||||||
|
"Debuff",
|
||||||
|
"NamedDebuff",
|
||||||
|
"NonCombatBuff",
|
||||||
|
"Cure",
|
||||||
|
"Buff"
|
||||||
|
],
|
||||||
|
"selectedItemBinding": {
|
||||||
|
"pullFormat": "${CastStackController.newCastStackItem.Get[type]}",
|
||||||
|
"autoPull": false,
|
||||||
|
"pullHook": {
|
||||||
|
"elementName": "CastStackController.events",
|
||||||
|
"flags": "global",
|
||||||
|
"event": "onNewCastStackItemChanged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eventHandlers": {
|
||||||
|
"onSelectionChanged": {
|
||||||
|
"type": "method",
|
||||||
|
"object": "CastStackController",
|
||||||
|
"method": "OnCastStackAbilityComboChange"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "Target",
|
||||||
|
"width": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "combobox",
|
||||||
|
"name": "castStack.ability.target",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"itemsBinding": {
|
||||||
|
"pullFormat": "${CastStackController.GetTargetOptions}",
|
||||||
|
"pullOnce": true
|
||||||
|
},
|
||||||
|
"selectedItemBinding": {
|
||||||
|
"pullFormat": "${CastStackController.newCastStackItem.Get[target]}",
|
||||||
|
"autoPull": false,
|
||||||
|
"pullHook": {
|
||||||
|
"elementName": "CastStackController.events",
|
||||||
|
"flags": "global",
|
||||||
|
"event": "onNewCastStackItemChanged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eventHandlers": {
|
||||||
|
"onSelectionChanged": {
|
||||||
|
"type": "method",
|
||||||
|
"object": "CastStackController",
|
||||||
|
"method": "OnCastStackAbilityComboChange"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "# targets",
|
||||||
|
"width": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.ability.targetCount",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"textBinding": {
|
||||||
|
"pullFormat": "${CastStackController.SafeGetNewCastStackItemProperty[targetCount]}",
|
||||||
|
"autoPull": false,
|
||||||
|
"pullHook": {
|
||||||
|
"elementName": "CastStackController.events",
|
||||||
|
"flags": "global",
|
||||||
|
"event": "onNewCastStackItemChanged"
|
||||||
|
},
|
||||||
|
"pushFormat": [
|
||||||
|
"CastStackController:SafeSetNewCastStackItemProperty[\"targetCount\",\"",
|
||||||
|
"\"]"
|
||||||
|
],
|
||||||
|
"autoPush": false
|
||||||
|
},
|
||||||
|
"hooks": {
|
||||||
|
"onLostFocus": {
|
||||||
|
"flags": "self",
|
||||||
|
"event": "lostKeyboardFocus",
|
||||||
|
"eventHandler": {
|
||||||
|
"type": "forward",
|
||||||
|
"event": "pushTextBinding",
|
||||||
|
"flags": "self"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"onLostMouseFocus": {
|
||||||
|
"flags": "self",
|
||||||
|
"event": "lostMouseFocus",
|
||||||
|
"eventHandler": {
|
||||||
|
"type": "forward",
|
||||||
|
"event": "pushTextBinding",
|
||||||
|
"flags": "self"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "HP/MP %",
|
||||||
|
"width": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.percent",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"textBinding": {
|
||||||
|
"pullFormat": "${CastStackController.SafeGetNewCastStackItemProperty[percent]}",
|
||||||
|
"autoPull": false,
|
||||||
|
"pullHook": {
|
||||||
|
"elementName": "CastStackController.events",
|
||||||
|
"flags": "global",
|
||||||
|
"event": "onNewCastStackItemChanged"
|
||||||
|
},
|
||||||
|
"pushFormat": [
|
||||||
|
"CastStackController:SafeSetNewCastStackItemProperty[\"percent\",\"",
|
||||||
|
"\"]"
|
||||||
|
],
|
||||||
|
"autoPush": false
|
||||||
|
},
|
||||||
|
"hooks": {
|
||||||
|
"onLostFocus": {
|
||||||
|
"flags": "self",
|
||||||
|
"event": "lostKeyboardFocus",
|
||||||
|
"eventHandler": {
|
||||||
|
"type": "forward",
|
||||||
|
"event": "pushTextBinding",
|
||||||
|
"flags": "self"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"onLostMouseFocus": {
|
||||||
|
"flags": "self",
|
||||||
|
"event": "lostMouseFocus",
|
||||||
|
"eventHandler": {
|
||||||
|
"type": "forward",
|
||||||
|
"event": "pushTextBinding",
|
||||||
|
"flags": "self"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "checkbox",
|
||||||
|
"name": "castStack.ignoreDuration",
|
||||||
|
"content": "Ignore Duration",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"margin": [
|
||||||
|
2,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "checkbox",
|
||||||
|
"name": "castStack.ignoreEncounterNukes",
|
||||||
|
"content": "Ignore Encounter Nukes",
|
||||||
|
"horizontalAlignment": "stretch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "checkbox",
|
||||||
|
"name": "castStack.ignoreAENukes",
|
||||||
|
"content": "Ignore AE Nukes",
|
||||||
|
"horizontalAlignment": "stretch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "checkbox",
|
||||||
|
"name": "castStack.maxIncrements",
|
||||||
|
"content": "Max Increments",
|
||||||
|
"horizontalAlignment": "stretch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "checkbox",
|
||||||
|
"name": "castStack.namedOnly",
|
||||||
|
"content": "Named Only",
|
||||||
|
"horizontalAlignment": "stretch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "Fervor",
|
||||||
|
"width": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.fervorRangeMin",
|
||||||
|
"width": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "-",
|
||||||
|
"font": {
|
||||||
|
"bold": true,
|
||||||
|
"height": 24
|
||||||
|
},
|
||||||
|
"margin": [
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"width": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.fervorRangeMax",
|
||||||
|
"width": 30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "Dissonance",
|
||||||
|
"width": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.dissonanceRangeMin",
|
||||||
|
"width": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "-",
|
||||||
|
"font": {
|
||||||
|
"bold": true,
|
||||||
|
"height": 24
|
||||||
|
},
|
||||||
|
"margin": [
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"width": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.dissonanceRangeMax",
|
||||||
|
"width": 30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "My HP",
|
||||||
|
"width": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.myHpRangeMin",
|
||||||
|
"width": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "-",
|
||||||
|
"font": {
|
||||||
|
"bold": true,
|
||||||
|
"height": 24
|
||||||
|
},
|
||||||
|
"margin": [
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"width": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.myHpRangeMax",
|
||||||
|
"width": 30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "My Power",
|
||||||
|
"width": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.myPowerRangeMin",
|
||||||
|
"width": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "-",
|
||||||
|
"font": {
|
||||||
|
"bold": true,
|
||||||
|
"height": 24
|
||||||
|
},
|
||||||
|
"margin": [
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"width": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.myPowerRangeMax",
|
||||||
|
"width": 30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "NPC HP",
|
||||||
|
"width": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.npcHpRangeMin",
|
||||||
|
"width": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "-",
|
||||||
|
"font": {
|
||||||
|
"bold": true,
|
||||||
|
"height": 24
|
||||||
|
},
|
||||||
|
"margin": [
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"width": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.npcHpRangeMax",
|
||||||
|
"width": 30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"margin": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "Aggro",
|
||||||
|
"width": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.aggroRangeMin",
|
||||||
|
"width": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "-",
|
||||||
|
"font": {
|
||||||
|
"bold": true,
|
||||||
|
"height": 24
|
||||||
|
},
|
||||||
|
"margin": [
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"width": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "textbox",
|
||||||
|
"name": "castStack.aggroRangeMax",
|
||||||
|
"width": 30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"widthFactor": 1,
|
||||||
|
"heightFactor": 1,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "Cast Order",
|
||||||
|
"widthFactor": 1,
|
||||||
|
"horizontalAlignment": "left"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "listbox",
|
||||||
|
"name": "castStack.castOrder",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"heightFactor": 0.9,
|
||||||
|
"itemsBinding": {
|
||||||
|
"pullFormat": "${CastStackController.profile.Get[castStack].Keys}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"name": "castStack.castOrder.edit",
|
||||||
|
"content": "Edit Entry",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"eventHandlers": {
|
||||||
|
"onRelease": [
|
||||||
|
"method",
|
||||||
|
"CastStackController",
|
||||||
|
"EditEntry"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"verticalAlignment": "stretch",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "stackpanel",
|
||||||
|
"orientation": "vertical",
|
||||||
|
"verticalAlignment": "stretch",
|
||||||
|
"horizontalAlignment": "left",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"name": "castStack.loadProfile",
|
||||||
|
"content": "Load Profile",
|
||||||
|
"horizontalAlignment": "left"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "combobox",
|
||||||
|
"name": "castStack.profileList",
|
||||||
|
"horizontalAlignment": "left",
|
||||||
|
"itemsBinding": {
|
||||||
|
"pullFormat": "${CastStackController.ProfileList}",
|
||||||
|
"autoPull": true,
|
||||||
|
"pullHook": {
|
||||||
|
"elementName": "CastStackController.events",
|
||||||
|
"flags": "global",
|
||||||
|
"event": "onProfileListChanged"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
174
lgui2/bot_window.json
Normal file
174
lgui2/bot_window.json
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://www.lavishsoft.com/schema/lgui2Package.json",
|
||||||
|
"includes": [
|
||||||
|
"bot_cast_stack.json"
|
||||||
|
],
|
||||||
|
"skin": {
|
||||||
|
"name": "MRSkin",
|
||||||
|
"brushes": {
|
||||||
|
"window.titleBar.backgroundBrush": {
|
||||||
|
"color": "#211C18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"templates": {
|
||||||
|
"window.title": {
|
||||||
|
"verticalAlignment": "center",
|
||||||
|
"margin": [
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"jsonTemplate": "default:button",
|
||||||
|
"margin": [
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"color": "#f4f3ee"
|
||||||
|
},
|
||||||
|
"checkbox": {
|
||||||
|
"jsonTemplate": "default:checkbox",
|
||||||
|
"margin": [
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"jsonTemplate": "default:window",
|
||||||
|
"backgroundBrush": {
|
||||||
|
"color": "#463f3a"
|
||||||
|
},
|
||||||
|
"color": "#f4f3ee",
|
||||||
|
"font": {
|
||||||
|
"face": "Segoe UI",
|
||||||
|
"height": 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"listbox.contentContainerFitWidth": {
|
||||||
|
"jsonTemplate": "listbox.contentContainer",
|
||||||
|
"horizontalScroll": "fit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "window",
|
||||||
|
"skin": "MRSkin",
|
||||||
|
"title": "MR Bot",
|
||||||
|
"name": "mr.bot.miniwindow",
|
||||||
|
"borderThickness": 2,
|
||||||
|
"hideOnClose": false,
|
||||||
|
"minSize": {
|
||||||
|
"width": 100,
|
||||||
|
"height": 50
|
||||||
|
},
|
||||||
|
"maxSize": {
|
||||||
|
"width": 150,
|
||||||
|
"height": 125
|
||||||
|
},
|
||||||
|
"eventHandlers": {
|
||||||
|
"onCloseButtonClick": [
|
||||||
|
"method",
|
||||||
|
"BotController",
|
||||||
|
"OnClose"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "stackpanel",
|
||||||
|
"uniform": true,
|
||||||
|
"heightFactor": 1,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"content": "${BotController.StartButtonText}",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"eventHandlers": {
|
||||||
|
"onRelease": [
|
||||||
|
"method",
|
||||||
|
"BotController",
|
||||||
|
"ToggleBot"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "button",
|
||||||
|
"content": "${BotController.SettingsButtonText}",
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"eventHandlers": {
|
||||||
|
"onRelease": [
|
||||||
|
"method",
|
||||||
|
"BotController",
|
||||||
|
"ToggleSettings"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "window",
|
||||||
|
"skin": "MRSkin",
|
||||||
|
"title": "MR Bot Settings",
|
||||||
|
"name": "mr.bot.settings",
|
||||||
|
"borderThickness": 2,
|
||||||
|
"hideOnClose": true,
|
||||||
|
"visibility": "hidden",
|
||||||
|
"minSize": {
|
||||||
|
"width": 450,
|
||||||
|
"height": 200
|
||||||
|
},
|
||||||
|
"maxSize": {
|
||||||
|
"height": 600,
|
||||||
|
"width": 800
|
||||||
|
},
|
||||||
|
"eventHandlers": {
|
||||||
|
"onCloseButtonClick": [
|
||||||
|
"method",
|
||||||
|
"BotController",
|
||||||
|
"OnCloseSettings"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "tabcontrol",
|
||||||
|
"heightFactor": 1,
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"verticalAlignment": "stretch",
|
||||||
|
"tabs": [
|
||||||
|
{
|
||||||
|
"type": "tab",
|
||||||
|
"header": "Cast Stack",
|
||||||
|
"name": "mr.bot.settings.castStack",
|
||||||
|
"content": {
|
||||||
|
"jsonTemplate": "settings.castStack",
|
||||||
|
"type": "stackpanel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tab",
|
||||||
|
"header": "General",
|
||||||
|
"content": {
|
||||||
|
"type": "dockpanel",
|
||||||
|
"_dock": "top",
|
||||||
|
"padding": 2,
|
||||||
|
"horizontalAlignment": "stretch",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "textblock",
|
||||||
|
"text": "General Settings",
|
||||||
|
"horizontalAlignment": "center",
|
||||||
|
"verticalAlignment": "center"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
29
scripts/bot_controller.iss
Normal file
29
scripts/bot_controller.iss
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
objectdef MRBotController
|
||||||
|
{
|
||||||
|
variable string test = "just a test"
|
||||||
|
method Initialize()
|
||||||
|
{
|
||||||
|
LGUI2:LoadPackageFile["${LavishScript.HomeDirectory}/scripts/mr/ui/bot_window.json"]
|
||||||
|
}
|
||||||
|
|
||||||
|
method Shutdown()
|
||||||
|
{
|
||||||
|
LGUI2:UnloadPackageFile["${LavishScript.HomeDirectory}/scripts/mr/ui/bot_window.json"]
|
||||||
|
}
|
||||||
|
|
||||||
|
method OnClose()
|
||||||
|
{
|
||||||
|
Event[MRBot_OnCloseButtonClicked]:Execute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable(global) MRBotController BotController
|
||||||
|
; variable(global) MRSettingsController SettingsController
|
||||||
|
|
||||||
|
function main()
|
||||||
|
{
|
||||||
|
while 1
|
||||||
|
{
|
||||||
|
wait 5
|
||||||
|
}
|
||||||
|
}
|
||||||
25
scripts/cast_stack_controller.iss
Normal file
25
scripts/cast_stack_controller.iss
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
objectdef MRCastStackController
|
||||||
|
{
|
||||||
|
method Initialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
method Shutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
method OnClose()
|
||||||
|
{
|
||||||
|
Event[OnCloseButtonClicked]:Execute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable(global) MRCastStackController CastStackController
|
||||||
|
|
||||||
|
function main()
|
||||||
|
{
|
||||||
|
while 1
|
||||||
|
{
|
||||||
|
wait 5
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,15 +3,13 @@
|
|||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
//#include <nlohmann/json.hpp>
|
|
||||||
//#include <picojson/picojson.h>
|
|
||||||
#include <json_struct/json_struct.h>
|
#include <json_struct/json_struct.h>
|
||||||
|
|
||||||
using namespace std;
|
#include "ScopedEnumBitwiseOperators.h"
|
||||||
//using json = nlohmann::json;
|
|
||||||
|
|
||||||
enum AbilityTypeFlags {
|
using namespace std;
|
||||||
|
|
||||||
|
enum class AbilityTypeFlags {
|
||||||
Debuff = 1,
|
Debuff = 1,
|
||||||
Buff = 2,
|
Buff = 2,
|
||||||
AE = 4,
|
AE = 4,
|
||||||
@ -32,13 +30,16 @@ enum AbilityTypeFlags {
|
|||||||
Self = 131072,
|
Self = 131072,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AbilityRequirementsFlags {
|
enum class AbilityRequirementsFlags {
|
||||||
NoEpic = 1,
|
NoEpic = 1,
|
||||||
Flanking = 2,
|
Flanking = 2,
|
||||||
Stealth = 4,
|
Stealth = 4,
|
||||||
Ranged = 8,
|
Ranged = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JS_ENUM_DECLARE_VALUE_PARSER(AbilityTypeFlags);
|
||||||
|
JS_ENUM_DECLARE_VALUE_PARSER(AbilityRequirementsFlags);
|
||||||
|
|
||||||
struct ExportedAbility {
|
struct ExportedAbility {
|
||||||
unsigned long Id;
|
unsigned long Id;
|
||||||
string Name;
|
string Name;
|
||||||
@ -75,8 +76,8 @@ struct ExportedAbility {
|
|||||||
float MaxRange;
|
float MaxRange;
|
||||||
unsigned int Damage;
|
unsigned int Damage;
|
||||||
vector<string> Effects;
|
vector<string> Effects;
|
||||||
unsigned long TypeFlags;
|
AbilityTypeFlags TypeFlags;
|
||||||
unsigned short RequirementsFlags;
|
AbilityRequirementsFlags RequirementsFlags;
|
||||||
|
|
||||||
JS_OBJ(Id, Name, Description, Tier, Level, HealthCost, PowerCost, DissonanceCost, SavageryCost, ConcentrationCost,
|
JS_OBJ(Id, Name, Description, Tier, Level, HealthCost, PowerCost, DissonanceCost, SavageryCost, ConcentrationCost,
|
||||||
MainIconID, HOIconID, CastingTime, RecoveryTime, RecastTime, MaxDuration, NumClasses, NumEffects,
|
MainIconID, HOIconID, CastingTime, RecoveryTime, RecastTime, MaxDuration, NumClasses, NumEffects,
|
||||||
|
|||||||
@ -4,35 +4,46 @@
|
|||||||
|
|
||||||
#include "ISXMr.h"
|
#include "ISXMr.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "Commands/ExportCommand.h"
|
#include "Tasks/BotTask.h"
|
||||||
|
#include "Tasks/ExportAbilitiesTask.h"
|
||||||
|
|
||||||
enum CommandType {
|
|
||||||
Export,
|
|
||||||
Test,
|
|
||||||
NotDefined
|
|
||||||
};
|
|
||||||
|
|
||||||
CommandType GetCommandType(const std::string &command) {
|
TaskTypeEnum GetTaskType(const std::string &command) {
|
||||||
if (command == "export" || command == "e") {
|
if (command == "export" || command == "e") {
|
||||||
return CommandType::Export;
|
return TaskTypeEnum::Export;
|
||||||
} else if (command == "test" || command == "t") {
|
|
||||||
return CommandType::Test;
|
|
||||||
}
|
}
|
||||||
return CommandType::NotDefined;
|
if (command == "test" || command == "t") {
|
||||||
|
return TaskTypeEnum::Test;
|
||||||
|
}
|
||||||
|
if (command == "bot" || command == "b") {
|
||||||
|
return TaskTypeEnum::Bot;
|
||||||
|
}
|
||||||
|
return TaskTypeEnum::NotDefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CMD_Mr(int argc, char *argv[]) {
|
int CMD_Mr(int argc, char *argv[]) {
|
||||||
const argh::parser cmdl(argv);
|
const argh::parser cmdl(argv);
|
||||||
switch (const auto commandType = GetCommandType(cmdl[1])) {
|
const auto taskType = GetTaskType(cmdl[1]);
|
||||||
case CommandType::Export:
|
|
||||||
executor.AddTask(std::make_shared<ExportCommand>());
|
if (executor.IsTaskTypeRunning(taskType)) {
|
||||||
|
logw << "Task of type " << cmdl[1] << " is already running" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (taskType) {
|
||||||
|
case TaskTypeEnum::Export:
|
||||||
|
executor.AddTask(std::make_shared<ExportAbilitiesTask>());
|
||||||
break;
|
break;
|
||||||
case CommandType::Test:
|
case TaskTypeEnum::Bot:
|
||||||
|
executor.AddTask(BotTask::Instance());
|
||||||
|
break;
|
||||||
|
case TaskTypeEnum::Test:
|
||||||
log << LogLevel::Info << "Test command" << std::endl;
|
log << LogLevel::Info << "Test command" << std::endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logw << "USAGE: mr [e|export]: Export abilities" << std::endl;
|
logw << "USAGE: mr [e|export]: Export abilities\n"
|
||||||
|
<< " mr [b|bot]: Run the combat bot" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
#ifndef COMMANDEXECUTOR_H
|
|
||||||
#define COMMANDEXECUTOR_H
|
|
||||||
#include <functional>
|
|
||||||
#include <future>
|
|
||||||
#include <mutex>
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
#include "ExecutableCommand.h"
|
|
||||||
|
|
||||||
|
|
||||||
class CommandExecutor {
|
|
||||||
public:
|
|
||||||
CommandExecutor(): stop(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
void AddTask(std::shared_ptr<ExecutableCommand> command);
|
|
||||||
|
|
||||||
void RemoveFinishedTasks();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Task {
|
|
||||||
std::shared_ptr<ExecutableCommand> command;
|
|
||||||
std::future<void> future;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Task> tasks;
|
|
||||||
mutable std::mutex queueMutex;
|
|
||||||
std::atomic<bool> stop;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //COMMANDEXECUTOR_H
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
#ifndef BASECOMMAND_H
|
|
||||||
#define BASECOMMAND_H
|
|
||||||
|
|
||||||
class ExecutableCommand {
|
|
||||||
public:
|
|
||||||
ExecutableCommand() : finished(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~ExecutableCommand() = default;
|
|
||||||
|
|
||||||
virtual void Execute() = 0;
|
|
||||||
|
|
||||||
void RequestStop() {
|
|
||||||
stopRequested = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsStopRequested() const {
|
|
||||||
return stopRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsFinished() const {
|
|
||||||
return finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void MarkFinished() {
|
|
||||||
finished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool stopRequested = false;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool finished;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //BASECOMMAND_H
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by marob on 12/27/2023.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef EXPORT_H
|
|
||||||
#define EXPORT_H
|
|
||||||
#include "ExecutableCommand.h"
|
|
||||||
|
|
||||||
|
|
||||||
class ExportCommand final : public ExecutableCommand {
|
|
||||||
public:
|
|
||||||
void Execute() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //EXPORT_H
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
#include "isxeq2/Character.h"
|
#include "isxeq2/Character.h"
|
||||||
#include "../lgui2/test.json.h"
|
#include "../lgui2/test.json.h"
|
||||||
#include "../scripts/bot.iss.h"
|
#include "../scripts/bot.iss.h"
|
||||||
#include "Commands/CommandExecutor.h"
|
#include "Tasks/TaskExecutor.h"
|
||||||
#pragma comment(lib,"isxdk.lib")
|
#pragma comment(lib,"isxdk.lib")
|
||||||
// The mandatory pre-setup function. Our name is "ISXMr", and the class is ISXMr.
|
// The mandatory pre-setup function. Our name is "ISXMr", and the class is ISXMr.
|
||||||
// This sets up a "ModulePath" variable which contains the path to this module in case we want it,
|
// This sets up a "ModulePath" variable which contains the path to this module in case we want it,
|
||||||
@ -85,23 +85,23 @@ bool ISXMr::Initialize(ISInterface *p_ISInterface) {
|
|||||||
* Most of the functionality in Initialize is completely optional and could be removed or
|
* Most of the functionality in Initialize is completely optional and could be removed or
|
||||||
* changed if so desired. The defaults are simply a suggestion that can be easily followed.
|
* changed if so desired. The defaults are simply a suggestion that can be easily followed.
|
||||||
*/
|
*/
|
||||||
constexpr size_t innerspacePathBufferLength = 255;
|
// constexpr size_t innerspacePathBufferLength = 255;
|
||||||
char innerspacePathBuffer[innerspacePathBufferLength];
|
// char innerspacePathBuffer[innerspacePathBufferLength];
|
||||||
const std::filesystem::path innerspacePath = p_ISInterface->GetInnerSpacePath(
|
// const std::filesystem::path innerspacePath = p_ISInterface->GetInnerSpacePath(
|
||||||
innerspacePathBuffer, innerspacePathBufferLength);
|
// innerspacePathBuffer, innerspacePathBufferLength);
|
||||||
std::filesystem::path fullPath = innerspacePath / R"(scripts\mr\ui\test.json)";
|
// std::filesystem::path fullPath = innerspacePath / R"(scripts\mr\ui\test.json)";
|
||||||
|
//
|
||||||
if (fullPath.has_parent_path() && !std::filesystem::exists(fullPath.parent_path())) {
|
// if (fullPath.has_parent_path() && !std::filesystem::exists(fullPath.parent_path())) {
|
||||||
std::filesystem::create_directories(fullPath.parent_path());
|
// std::filesystem::create_directories(fullPath.parent_path());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
std::ofstream file(fullPath, std::ios::binary);
|
// std::ofstream file(fullPath, std::ios::binary);
|
||||||
if (!file) {
|
// if (!file) {
|
||||||
std::cerr << "Error opening file for writing: " << fullPath << std::endl;
|
// std::cerr << "Error opening file for writing: " << fullPath << std::endl;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
file.write(reinterpret_cast<const char *>(test_json), test_json_len);
|
// file.write(reinterpret_cast<const char *>(test_json), test_json_len);
|
||||||
file.close();
|
// file.close();
|
||||||
|
|
||||||
|
|
||||||
//__try // exception handling. See __except below.
|
//__try // exception handling. See __except below.
|
||||||
@ -141,7 +141,7 @@ bool ISXMr::Initialize(ISInterface *p_ISInterface) {
|
|||||||
// Register any text triggers built into ISXMr
|
// Register any text triggers built into ISXMr
|
||||||
RegisterTriggers();
|
RegisterTriggers();
|
||||||
|
|
||||||
pISInterface->RunScriptFromBuffer("mrbot", reinterpret_cast<const char *>(bot_iss), bot_iss_len);
|
// pISInterface->RunScriptFromBuffer("mrbot", reinterpret_cast<const char *>(bot_iss), bot_iss_len);
|
||||||
printf("ISXMr version %s Loaded", Mr_Version);
|
printf("ISXMr version %s Loaded", Mr_Version);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -315,11 +315,11 @@ void __cdecl OnCloseButtonClicked(int argc, char *argv[], PLSOBJECT lsObj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ISXMr::RegisterEvents() {
|
void ISXMr::RegisterEvents() {
|
||||||
onGetTargetEventId = pISInterface->RegisterEvent("OnGetTarget");
|
// onGetTargetEventId = pISInterface->RegisterEvent("OnGetTarget");
|
||||||
pISInterface->AttachEventTarget(onGetTargetEventId, OnGetTargetEvent);
|
// pISInterface->AttachEventTarget(onGetTargetEventId, OnGetTargetEvent);
|
||||||
|
//
|
||||||
onCloseButtonClickedEventId = pISInterface->RegisterEvent("OnCloseButtonClicked");
|
// onCloseButtonClickedEventId = pISInterface->RegisterEvent("OnCloseButtonClicked");
|
||||||
pISInterface->AttachEventTarget(onCloseButtonClickedEventId, OnCloseButtonClicked);
|
// pISInterface->AttachEventTarget(onCloseButtonClickedEventId, OnCloseButtonClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISXMr::DisconnectServices() {
|
void ISXMr::DisconnectServices() {
|
||||||
@ -382,14 +382,14 @@ void ISXMr::UnRegisterServices() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ISXMr::UnRegisterEvents() {
|
void ISXMr::UnRegisterEvents() {
|
||||||
pISInterface->DetachEventTarget(onGetTargetEventId, OnGetTargetEvent);
|
// pISInterface->DetachEventTarget(onGetTargetEventId, OnGetTargetEvent);
|
||||||
pISInterface->UnregisterEvent(onGetTargetEventId);
|
// pISInterface->UnregisterEvent(onGetTargetEventId);
|
||||||
|
//
|
||||||
pISInterface->DetachEventTarget(onCloseButtonClickedEventId, OnCloseButtonClicked);
|
// pISInterface->DetachEventTarget(onCloseButtonClickedEventId, OnCloseButtonClicked);
|
||||||
pISInterface->UnregisterEvent(onCloseButtonClickedEventId);
|
// pISInterface->UnregisterEvent(onCloseButtonClickedEventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandExecutor executor;
|
TaskExecutor executor;
|
||||||
|
|
||||||
std::chrono::milliseconds interval(100);;
|
std::chrono::milliseconds interval(100);;
|
||||||
std::chrono::steady_clock::time_point nextCleanup = std::chrono::steady_clock::now() + interval;
|
std::chrono::steady_clock::time_point nextCleanup = std::chrono::steady_clock::now() + interval;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#include <ISXDK.h>
|
#include <ISXDK.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "Commands/CommandExecutor.h"
|
#include "Tasks/TaskExecutor.h"
|
||||||
|
|
||||||
|
|
||||||
class ISXMr :
|
class ISXMr :
|
||||||
@ -56,7 +56,7 @@ extern HISXSERVICE hHTTPService;
|
|||||||
extern HISXSERVICE hTriggerService;
|
extern HISXSERVICE hTriggerService;
|
||||||
extern HISXSERVICE hSystemService;
|
extern HISXSERVICE hSystemService;
|
||||||
|
|
||||||
extern CommandExecutor executor;;
|
extern TaskExecutor executor;;
|
||||||
|
|
||||||
extern ISXMr *pExtension;
|
extern ISXMr *pExtension;
|
||||||
#define printf pISInterface->Printf
|
#define printf pISInterface->Printf
|
||||||
|
|||||||
@ -75,7 +75,7 @@ private:
|
|||||||
const auto now = std::chrono::system_clock::now();
|
const auto now = std::chrono::system_clock::now();
|
||||||
const auto now_c = std::chrono::system_clock::to_time_t(now);
|
const auto now_c = std::chrono::system_clock::to_time_t(now);
|
||||||
|
|
||||||
std::tm now_tm;
|
std::tm now_tm = {};
|
||||||
localtime_s(&now_tm, &now_c); // Thread-safe on Windows
|
localtime_s(&now_tm, &now_c); // Thread-safe on Windows
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|||||||
59
src/ScopedEnumBitwiseOperators.h
Normal file
59
src/ScopedEnumBitwiseOperators.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
#ifndef SCOPEDENUMBITWISEOPERATORS_H
|
||||||
|
#define SCOPEDENUMBITWISEOPERATORS_H
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
std::enable_if_t<std::is_enum_v<Enum>, Enum>
|
||||||
|
operator^(Enum lhs, Enum rhs) {
|
||||||
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
|
return static_cast<Enum>(static_cast<underlying>(lhs) ^ static_cast<underlying>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
std::enable_if_t<std::is_enum_v<Enum>, Enum>
|
||||||
|
operator|(Enum lhs, Enum rhs) {
|
||||||
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
|
return static_cast<Enum>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
std::enable_if_t<std::is_enum_v<Enum>, Enum>
|
||||||
|
operator&(Enum lhs, Enum rhs) {
|
||||||
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
|
return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
std::enable_if_t<std::is_enum_v<Enum>, Enum>
|
||||||
|
operator~(Enum rhs) {
|
||||||
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
|
return static_cast<Enum>(~static_cast<underlying>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
std::enable_if_t<std::is_enum_v<Enum>, Enum>
|
||||||
|
operator|=(Enum &lhs, Enum rhs) {
|
||||||
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
|
lhs = static_cast<Enum>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
std::enable_if_t<std::is_enum_v<Enum>, Enum>
|
||||||
|
operator&=(Enum &lhs, Enum rhs) {
|
||||||
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
|
lhs = static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
std::enable_if_t<std::is_enum_v<Enum>, Enum>
|
||||||
|
operator^=(Enum &lhs, Enum rhs) {
|
||||||
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
|
lhs = static_cast<Enum>(static_cast<underlying>(lhs) ^ static_cast<underlying>(rhs));
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SCOPEDENUMBITWISEOPERATORS_H
|
||||||
77
src/Tasks/BotTask.cpp
Normal file
77
src/Tasks/BotTask.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "BotTask.h"
|
||||||
|
#include "ISXMr.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "../../lgui2/UpdateUIPackageFile.h"
|
||||||
|
#include "../../lgui2/bot_window.json.h"
|
||||||
|
#include "../../lgui2/bot_cast_stack.json.h"
|
||||||
|
#include "../../scripts/bot_controller.iss.h"
|
||||||
|
|
||||||
|
|
||||||
|
std::weak_ptr<BotTask> BotTask::instance;
|
||||||
|
|
||||||
|
std::shared_ptr<BotTask> BotTask::Instance() {
|
||||||
|
auto existingInstance = instance.lock();
|
||||||
|
if (!existingInstance) {
|
||||||
|
existingInstance = std::shared_ptr<BotTask>(new BotTask());
|
||||||
|
instance = existingInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
BotTask::BotTask() {
|
||||||
|
UpdateUIPackageFile(
|
||||||
|
"bot_window.json",
|
||||||
|
reinterpret_cast<const char *>(bot_window_json),
|
||||||
|
bot_window_json_len,
|
||||||
|
bot_window_json_last_modified
|
||||||
|
);
|
||||||
|
|
||||||
|
UpdateUIPackageFile(
|
||||||
|
"bot_cast_stack.json",
|
||||||
|
reinterpret_cast<const char *>(bot_cast_stack_json),
|
||||||
|
bot_cast_stack_json_len,
|
||||||
|
bot_cast_stack_json_last_modified
|
||||||
|
);
|
||||||
|
|
||||||
|
pISInterface->RunScriptFromBuffer(
|
||||||
|
ScriptName.c_str(),
|
||||||
|
reinterpret_cast<const char *>(bot_controller_iss),
|
||||||
|
bot_controller_iss_len
|
||||||
|
);
|
||||||
|
|
||||||
|
botController = make_shared<LSObject>(LSObject::FromDataParse("${BotController}"));
|
||||||
|
this->onCloseButtonClickedEventId = pISInterface->RegisterEvent(OnClosedEventName.c_str());
|
||||||
|
pISInterface->AttachEventTarget(this->onCloseButtonClickedEventId,
|
||||||
|
&BotTask::OnCloseEventHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl BotTask::OnCloseEventHandler(int argc, char *argv[], PLSOBJECT plsObject) {
|
||||||
|
Instance()->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BotTask::~BotTask() {
|
||||||
|
const std::string bufferScriptName = "Buffer:" + ScriptName;
|
||||||
|
pISInterface->EndScript(bufferScriptName.c_str());
|
||||||
|
pISInterface->DetachEventTarget(this->onCloseButtonClickedEventId, &BotTask::OnCloseEventHandler);
|
||||||
|
pISInterface->UnregisterEvent(this->onCloseButtonClickedEventId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BotTask::Execute() {
|
||||||
|
while (!this->stopRequested && !this->IsFinished()) {
|
||||||
|
// sleep for 100 ms
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BotTask::Close() {
|
||||||
|
this->MarkFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskTypeEnum BotTask::TaskType() const {
|
||||||
|
return TaskTypeEnum::Bot;
|
||||||
|
}
|
||||||
37
src/Tasks/BotTask.h
Normal file
37
src/Tasks/BotTask.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef BOTTASK_H
|
||||||
|
#define BOTTASK_H
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ExecutableTask.h"
|
||||||
|
#include "isxeq2/LSObject.h"
|
||||||
|
|
||||||
|
class BotTask final : public ExecutableTask, public std::enable_shared_from_this<BotTask> {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<BotTask> Instance();
|
||||||
|
|
||||||
|
~BotTask() override;
|
||||||
|
|
||||||
|
void Execute() override;
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
[[nodiscard]] TaskTypeEnum TaskType() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BotTask();
|
||||||
|
|
||||||
|
static std::weak_ptr<BotTask> instance;
|
||||||
|
|
||||||
|
const std::string ScriptName = "MRBot";
|
||||||
|
const std::string OnClosedEventName = "MRBot_OnCloseButtonClicked";
|
||||||
|
|
||||||
|
std::shared_ptr<LSObject> botController;
|
||||||
|
std::shared_ptr<LSObject> settingsController;
|
||||||
|
|
||||||
|
u_int onCloseButtonClickedEventId = 0;
|
||||||
|
|
||||||
|
static void __cdecl OnCloseEventHandler(int argc, char *argv[], PLSOBJECT plsObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //BOTTASK_H
|
||||||
46
src/Tasks/ExecutableTask.h
Normal file
46
src/Tasks/ExecutableTask.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef BASETASK_H
|
||||||
|
#define BASETASK_H
|
||||||
|
|
||||||
|
enum class TaskTypeEnum {
|
||||||
|
Export,
|
||||||
|
Bot,
|
||||||
|
Test,
|
||||||
|
NotDefined
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExecutableTask {
|
||||||
|
public:
|
||||||
|
ExecutableTask() : finished(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ExecutableTask() = default;
|
||||||
|
|
||||||
|
virtual void Execute() = 0;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
virtual TaskTypeEnum TaskType() const = 0;
|
||||||
|
|
||||||
|
void RequestStop() {
|
||||||
|
stopRequested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsStopRequested() const {
|
||||||
|
return stopRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsFinished() const {
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void MarkFinished() {
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stopRequested = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool finished;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //BASETASK_H
|
||||||
@ -5,7 +5,7 @@
|
|||||||
#include<json_struct/json_struct.h>
|
#include<json_struct/json_struct.h>
|
||||||
|
|
||||||
#include "ISXMr.h"
|
#include "ISXMr.h"
|
||||||
#include "ExportCommand.h"
|
#include "ExportAbilitiesTask.h"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ AbilityInfo GetAbilityInfo(const int idx) {
|
|||||||
return ability.GetAbilityInfo();
|
return ability.GetAbilityInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportCommand::Execute() {
|
void ExportAbilitiesTask::Execute() {
|
||||||
try {
|
try {
|
||||||
log << "Exporting abilities" << endl;
|
log << "Exporting abilities" << endl;
|
||||||
const auto numAbilities = ExtensionTLOs::Me().NumAbilities();
|
const auto numAbilities = ExtensionTLOs::Me().NumAbilities();
|
||||||
15
src/Tasks/ExportAbilitiesTask.h
Normal file
15
src/Tasks/ExportAbilitiesTask.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef EXPORTABILITIESTASK_H
|
||||||
|
#define EXPORTABILITIESTASK_H
|
||||||
|
#include "ExecutableTask.h"
|
||||||
|
|
||||||
|
class ExportAbilitiesTask final : public ExecutableTask {
|
||||||
|
public:
|
||||||
|
void Execute() override;
|
||||||
|
|
||||||
|
[[nodiscard]] TaskTypeEnum TaskType() const override {
|
||||||
|
return TaskTypeEnum::Export;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //EXPORTABILITIESTASK_H
|
||||||
@ -1,9 +1,9 @@
|
|||||||
#include "CommandExecutor.h"
|
#include "TaskExecutor.h"
|
||||||
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
|
|
||||||
void CommandExecutor::Shutdown() {
|
void TaskExecutor::Shutdown() {
|
||||||
stop = true;
|
stop = true;
|
||||||
for (auto &[command, future]: tasks) {
|
for (auto &[command, future]: tasks) {
|
||||||
if (future.valid()) {
|
if (future.valid()) {
|
||||||
@ -22,7 +22,7 @@ void CommandExecutor::Shutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CommandExecutor::AddTask(std::shared_ptr<ExecutableCommand> command) {
|
void TaskExecutor::AddTask(std::shared_ptr<ExecutableTask> command) {
|
||||||
std::lock_guard<std::mutex> lock(queueMutex);
|
std::lock_guard<std::mutex> lock(queueMutex);
|
||||||
std::future<void> future = std::async(std::launch::async, [command]() {
|
std::future<void> future = std::async(std::launch::async, [command]() {
|
||||||
try {
|
try {
|
||||||
@ -34,7 +34,15 @@ void CommandExecutor::AddTask(std::shared_ptr<ExecutableCommand> command) {
|
|||||||
tasks.push_back({command, std::move(future)});
|
tasks.push_back({command, std::move(future)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandExecutor::RemoveFinishedTasks() {
|
bool TaskExecutor::IsTaskTypeRunning(TaskTypeEnum taskType) const {
|
||||||
|
std::lock_guard lock(queueMutex);
|
||||||
|
return std::ranges::any_of(tasks, [taskType](const Task &task) {
|
||||||
|
return task.task->TaskType() == taskType;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TaskExecutor::RemoveFinishedTasks() {
|
||||||
std::lock_guard<std::mutex> lock(queueMutex);
|
std::lock_guard<std::mutex> lock(queueMutex);
|
||||||
std::erase_if(tasks, [](Task &task) {
|
std::erase_if(tasks, [](Task &task) {
|
||||||
if (task.future.valid() && task.future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
|
if (task.future.valid() && task.future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
|
||||||
42
src/Tasks/TaskExecutor.h
Normal file
42
src/Tasks/TaskExecutor.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef TASKEXECUTOR_H
|
||||||
|
#define TASKEXECUTOR_H
|
||||||
|
#include <functional>
|
||||||
|
#include <future>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include "ExecutableTask.h"
|
||||||
|
|
||||||
|
enum TaskType {
|
||||||
|
Export,
|
||||||
|
Bot,
|
||||||
|
Test,
|
||||||
|
NotDefined
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaskExecutor {
|
||||||
|
public:
|
||||||
|
TaskExecutor(): stop(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
void AddTask(std::shared_ptr<ExecutableTask> command);
|
||||||
|
|
||||||
|
bool IsTaskTypeRunning(TaskTypeEnum taskType) const;
|
||||||
|
|
||||||
|
void RemoveFinishedTasks();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Task {
|
||||||
|
std::shared_ptr<ExecutableTask> task;
|
||||||
|
std::future<void> future;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Task> tasks;
|
||||||
|
mutable std::mutex queueMutex;
|
||||||
|
std::atomic<bool> stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //TASKEXECUTOR_H
|
||||||
@ -1,37 +0,0 @@
|
|||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
std::chrono::system_clock::time_point ParseEmbeddedTimestamp(const std::string& timestamp) {
|
|
||||||
std::tm tm = {};
|
|
||||||
std::istringstream ss(timestamp);
|
|
||||||
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
|
|
||||||
return std::chrono::system_clock::from_time_t(std::mktime(&tm));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteUIFileToDiskIfChanged(
|
|
||||||
const std::string& filePath,
|
|
||||||
const unsigned char* data,
|
|
||||||
const size_t length,
|
|
||||||
const std::string& lastModified) {
|
|
||||||
|
|
||||||
auto embeddedTimestamp = ParseEmbeddedTimestamp(lastModified);
|
|
||||||
|
|
||||||
if (std::filesystem::exists(filePath)) {
|
|
||||||
const auto lastWriteTime = std::filesystem::last_write_time(filePath);
|
|
||||||
|
|
||||||
// Convert file_time_type to system_clock::time_point
|
|
||||||
const auto lastWriteTimeTp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
|
|
||||||
lastWriteTime - std::filesystem::file_time_type::clock::now() + std::chrono::system_clock::now()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (lastWriteTimeTp < embeddedTimestamp) {
|
|
||||||
std::ofstream file(filePath, std::ios::binary);
|
|
||||||
file.write(reinterpret_cast<const char*>(data), length);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
std::ofstream file(filePath, std::ios::binary);
|
|
||||||
file.write(reinterpret_cast<const char*>(data), length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -76,23 +76,23 @@ ExportedAbility Ability::ToExportedAbility() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (RequiresStealth(exportedAbility.Effects)) {
|
if (RequiresStealth(exportedAbility.Effects)) {
|
||||||
exportedAbility.RequirementsFlags |= Stealth;
|
exportedAbility.RequirementsFlags |= AbilityRequirementsFlags::Stealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RequiresFlanking(exportedAbility.Effects)) {
|
if (RequiresFlanking(exportedAbility.Effects)) {
|
||||||
exportedAbility.RequirementsFlags |= Flanking;
|
exportedAbility.RequirementsFlags |= AbilityRequirementsFlags::Flanking;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RequiresNonEpic(exportedAbility.Effects)) {
|
if (RequiresNonEpic(exportedAbility.Effects)) {
|
||||||
exportedAbility.RequirementsFlags |= NoEpic;
|
exportedAbility.RequirementsFlags |= AbilityRequirementsFlags::NoEpic;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsStun(exportedAbility.Effects)) {
|
if (IsStun(exportedAbility.Effects)) {
|
||||||
exportedAbility.TypeFlags |= Stun;
|
exportedAbility.TypeFlags |= AbilityTypeFlags::Stun;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsInterrupt(exportedAbility.Effects)) {
|
if (IsInterrupt(exportedAbility.Effects)) {
|
||||||
exportedAbility.TypeFlags |= Interrupt;
|
exportedAbility.TypeFlags |= AbilityTypeFlags::Interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public:
|
|||||||
// Use a fold expression to convert each argument to a string
|
// Use a fold expression to convert each argument to a string
|
||||||
const std::vector<std::string> arguments = {toString(args)...};
|
const std::vector<std::string> arguments = {toString(args)...};
|
||||||
|
|
||||||
const int argc = arguments.size();
|
const size_t argc = arguments.size();
|
||||||
std::vector<char *> argv;
|
std::vector<char *> argv;
|
||||||
|
|
||||||
for (auto &arg: arguments) {
|
for (auto &arg: arguments) {
|
||||||
@ -49,7 +49,7 @@ public:
|
|||||||
if (const auto result = this->lsObject->Type->GetMemberEx(
|
if (const auto result = this->lsObject->Type->GetMemberEx(
|
||||||
this->lsObject->GetObjectData(),
|
this->lsObject->GetObjectData(),
|
||||||
const_cast<char *>(memberName.c_str()),
|
const_cast<char *>(memberName.c_str()),
|
||||||
argc,
|
static_cast<int>(argc),
|
||||||
argv.data(),
|
argv.data(),
|
||||||
response
|
response
|
||||||
); !result) {
|
); !result) {
|
||||||
@ -75,7 +75,7 @@ public:
|
|||||||
// Use a fold expression to convert each argument to a string
|
// Use a fold expression to convert each argument to a string
|
||||||
const std::vector<std::string> arguments = {toString(args)...};
|
const std::vector<std::string> arguments = {toString(args)...};
|
||||||
|
|
||||||
const int argc = arguments.size();
|
const size_t argc = arguments.size();
|
||||||
std::vector<char *> argv;
|
std::vector<char *> argv;
|
||||||
|
|
||||||
for (auto &arg: arguments) {
|
for (auto &arg: arguments) {
|
||||||
@ -85,14 +85,22 @@ public:
|
|||||||
this->lsObject->Type->GetMethodEx(
|
this->lsObject->Type->GetMethodEx(
|
||||||
this->lsObject->GetObjectData(),
|
this->lsObject->GetObjectData(),
|
||||||
const_cast<char *>(methodName.c_str()),
|
const_cast<char *>(methodName.c_str()),
|
||||||
argc,
|
static_cast<int>(argc),
|
||||||
argv.data());
|
argv.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid() const {
|
[[nodiscard]] bool IsValid() const {
|
||||||
return this->lsObject.has_value();
|
return this->lsObject.has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LSObject FromDataParse(const std::string &dataToParse) {
|
||||||
|
if (LSOBJECT rawObject; pISInterface->DataParse(dataToParse.c_str(), rawObject)) {
|
||||||
|
return LSObject(rawObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LSObject(nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
optional<LSOBJECT> lsObject;
|
optional<LSOBJECT> lsObject;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user