L0G-101086 Automated log uploads
A collection of scripts intended for posting links to uploaded EVTC encounter report files generated by ArcDPS. It supports uploading to both to dps.report and automatically generating a discord comment linking back to the uploaded files.
Previous versions supported uploading to gw2raidar, but due to the nature of their API, this support was removed as it is problematic to obtain the permalinks for the raidar pages.
It is authored by Jacob Keller a.k.a. platinummyr and is available under a simple 3-clause BSD license.
- Guild Wars 2
- PowerShell 5
The scripts are intended for uploading EVTC reports generated for Guild Wars 2, using the ArcDPS addon.
The scripts are written in Power Shell and are known to work with the most recent version 5 release. They do not currently work with Powershell 6. Generally Power Shell 5 is installed in Windows by default. More information can be found at Microsoft's documentation
Pull requests to add Powershell 6 support are welcome, but it is not something I plan on doing soon.
Due to the complexity of including files when using the PowerShell Invoke-RestMethod cmdlt, the scripts rely on the RestSharp .NET library for handling some of the REST APIs. The GitHub release of this project include a copy of the RestSharp.dll, as it is available under the Apache 2.0 License.
Installation and Setup
The scripts require some manual setup in order to work. First, download the scripts and place them somewhere convenient on your system. You will also need the RestSharp.dll and simpleArcParse.exe binaries. You can download these from the GitHub release page or compile them yourself manually. simpleArcParse code is available in the repository. RestSharp is available on its GitHub page
The scripts rely on a configuration file written in in JSON for setup. See the configuration section for more details about the various options and controls available.
Once you've updated the sample configuration and renamed it, you should be able to run the upload-logs script to upload logs to dps.report. Then you can run the format-encounters script to create and publish a comment with links to the different encounters run since the last time you ran the format script.
The update-arcpds script is useful for automatically updating ArcDPS and related utilities. The launcher script is useful for those that use Gw2 Launch Buddy. It will run the update-arcdps.ps1 script first, and then start Launch Buddy.
There are a few known issues that you may encounter. If you run into issues not documented here, please file an issue or conact the author for assistance.
RestSharp.dll is not loading?
You may see an issue with loading the RestSharp.dll file, similar to the following exception:
Add-Type : Could not load file or assembly 'file:///C:\Users\Corey\Documents\Guild Wars 2\addons\arcdps\RestSharp.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515) At C:\Users\Corey\Documents\Guild Wars 2\addons\arcdps\upload-logs.ps1:98 char:1 + Add-Type -Path $config.restsharp_path + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Add-Type], FileLoadException + FullyQualifiedErrorId : System.IO.FileLoadException,Microsoft.PowerShell.Commands.AddTypeCommand
This is likely caused because Windows needs to be told to unblock the file, which can be done from the powershell console like so:
Unblock-File -Path RestSharp.dll
This will not take affect until you reload the PowerShell console.
simpleArcParse.exe not running, disappearing on call to upload-logs.ps1
Some antivirus software may prevent the execution of simpleArcParse.exe, and possibly quarentine or even delete the exeucutable. You might see an exception when upload-logs.ps1 is run.
If this is happening, you should check antivirus software and ensure that the simpleArcParse executable is not blocked.
Powershell Execution Policy
These scripts have been self-signed with a private key, which was not generated by a public key authority. Thus, even though the scripts are signed, your computer may not automatically trust them.
The simplest fix is to unblock the files using the Unblock-File cmdlet. This will allow the script to be run assuming your default execution policy is RemoteSigned. For more information about the execution policies, see the Microsoft's Execution Policies page.
The Configuration File
Configuration for the scripts is located in l0g-101086-config.json, which is a JSON file containing various parameters that control how the scripts operate. A sample configuration is located at l0g-101086-config.sample.json, which is a good starting point.
You can also set the L0G_101086_CONFIG_FILE environment variable to change the default config file location to load a different file, if desired.
This field represents the configuration version format. It should not be changed unless you know what you are doing. Currently the valid values are "1" and "2". The configure-v2-builds.ps1 script is provided to migrate from the deprecated v1 configuration to the newer v2 configuration. The current sample configuration is already version 2, so this script is only useful for those who ran the older versions of the script which used the previous v1 configuration format.
This field enables debug oprations, and is generally only useful if you are developing additions to the scripts. The sample configuration sets this to false, and for normal use it should not be set to true. Currently this just enables displaying extra data to the console as the scripts run.
If set to true, this enables the update-arcdps.ps1 script to grab experimental versions of ArcDPS. If there is no experimental version of ArcDPS available, it will fall back to the regular version. Set this to true if you wish to use experimental versions of ArcDPS, or false if you only wish to use the normal stable releases. Only affects update-arcdps.ps1.
This variable should be set to the path of the arcdps.cbtlogs directory which contains your generated EVTC files. The scripts understand to interpret the %UserProfile% string as the User Profile environment variable. This must be set for the upload-logs.ps1 and format-encounters.ps1 scripts to work correctly
This variable specifies a path to store the JSON data that is sent to discord webhooks, and is used to save potential data incase there are issues with the discord posts
Specifies a path to a file which contains the timestamp of the last time that the format-encounters.ps1 script was run. The format-encounters.ps1 script will only publish encounters which are newer than this time stamp, and will update the timestamp after running.
Specifies the path to a file which contains the timestamp of the last time that the upload-logs.ps1 script was run. The upload-logs.ps1 script will only upload logs newer than this timestamp, and will update the timestamp after running. This is used to avoid uploading old encounters.
Optional configuration specifying the default amount of time to look backwards for encounters when no last_format_file or last_upload_file exist yet. This prevents the script from attempting to upload all encounters on the initial run. Specified in "hours ago", with the default being "48 hours ago" to limit the initial upload to 2 days.
This variable configures the path to the simpleArcParse.exe. This must be set in order to enable the upload-logs.ps1 script to work properly.
Specifies the path to the log file for the upload-logs.ps1 script. Useful output will be stored in this file, and it may be useful for debugging, or checking if files have been uploaded properly.
Specifies the path to the log file for the format-encounters.ps1 script. Useful output will be stored in this file, and it may be useful for debugging why some encounters are not posted properly.
Specifies the path to where Guild Wars 2 is installed. Used by the update-arcdps.ps1 script to figure out where to install the ArcDPS dlls
Specifies the path to where the GW2 Launch Buddy executable is installed. Only used by the launcher.ps1 script to execute Gw2 Launch Buddy after updating ArcDPS.
Specifies the path to where .dll backups should be made. Used by the update-arcdps.ps1 script to backup .dll files before over-writing them when downloading updates.
The dps.report API token to use when uploading to dps.report. This should be set to a random string that you keep safe like a password, as it is used by dps.report to allow looking up which encounters you uploaded.
Sets the dps.report generator to use. Can be "ei" for EliteInsights, or "rh" for the old RaidHeros. It is recommended to use "ei".
Set to true to "no" to disable uploading to dps.report. Set to "successful" to enable uploading only the successful encounters to dps.report. Set to "all" to upload all encounters to dps.report. The default is to upload only successful encounters. Note that "none" is an alternative spelling of "no", and "yes" is an alternative spelling of "all".
The guild subsection is used to configure which "guild" an encounter was run by. This is primarily used as a method to allow posting different enounters to different guild discords. Note that guilds is an array object, so the configuration file supports multiple different guilds, with their own options. See the l0g-101086-config.multipleguilds.json for an example configuration file that has multiple guilds configured.
The name of the guild, used as a shorthand when posting to discord
A number indicating priority when deciding which guild may be considered as the main guild for an encounter. Lower numbers win ties based on other data.
A map of guild members associated with this guild, and if available, their discord ping identifier. The players are also used as the determiner for which players are part of the guild. See Configuring Discord Accounts for more information about how to obtain the discord account ids.
The show_players configuration can be used to optionally configure how the discord_map is used to convert gw2 account names when displaying. It can be set to "none", which will cause no player names to be shown. It can be set to "discord_if_possible", causing the player list to show both discord pings based on the discord_map, and fallback to account names if there is no mapping availble. It can be set to "discord_only", which causes the player list to only include players who are in the discord_map, and it can be set to "accounts_only" to disable the mapping behavior and just show account names. The default value (and older script behavior) is "discord_if_possible".
Can be set to a string which will prefix the player list. For example, it could be set to @526255792958078987 to add an "@here" ping. Similar to discord names, you must use the ID from discord in the ping for it to be displayed properly. If show_players is set to "none", then only the prefix will be displayed.
The minimum number of players required to recognize the encounter as part of this guild. Useful to exclude treating the guild as the main guild unless a minmum number of players from the guild have joined. Uses the discord_map as the source of data for players in the guild. Note that if an encounter does not have enough players to reach the minimum threshold for any guild in the configuration file, then it will not be posted. For this reason, it is recommended to have at least one guild with a threshold of zero to avoid this.
The URL for the discord webhook to use when posting to this guild.
The URL for a thumbnail icon to include in the discord embed post. If unset or set to the empty string, then no image will be included.
A mapping between boss encounters and discord emoji ids to use when posting for this guild. The IDs are server specific, so they must be emojis uploaded to that server. See Configuring Emojis for more details.
A boolean indicating if this guild should have raid encounters posted to it. If set to false, then the guild will not be assigned as the owner of a raid encounter. If set to true, then the raid encounter may be posted to this discord webook URL. If not set, the default is true.
A boolean indicating if this guild should have fractal encounters posted to it. If set to false, then this guild will not be assigned as the owner of a fractal encounter. If set to true, then fractal encounters may be posted to this discord webhook URL.
A boolean indicating if this guild should have golem training encounters posted to it. If set to false, then this guild will not be assigned as the owner of a golem encounter. If set to true, the golem encounters may be posted to this discord webhook URL.
If set to true, all posts will also be copied to this guild's discord webhook URL. Useful to have a single server which receives all posts, while other guild discords only receive posts for their own guild.
An optional configuration setting that can be used to disable showing the encounter duration when publishing. Set to false to disable including the duration when formatting the encounters. If the value is not set, it will default to true.
An optional configuration setting that can be used to enable publishing all encounters, including non-successful encounters for a given guild. Set to "none" to disable publishing any encounters for this guild. Set to "failed" to only publish failed encounters for this guild. Set to "succesful" to only publish successful encounters for this guild. Set to "all" to publish all encounters to this guild. The default value is "successful"
The simpleArcParse utility is written in C++ so depends on a C++ compiler. Visual Studio should work, but I used CodeBlocks with the MinGW compiler suite. I have a CodeBlocks project file included in the repository which should work out of the box.
If you do not wish to bother compiling simpleArcParse, the Github Release page can be used to download a precompiled binary of the program. You can download this and update the configuration to point to it instead of compiling yourself.
There are several scripts, and it may be confusing which ones to run. The primary two scripts for uploading logs are the upload-logs.ps1 script, and the format-encounters.ps1 script. Other scripts may be useful to run once during initial setup, or for updating ArcDPS.
For the main scripts, shortcut files are provided which make running the script as easy as double clicking.
The following sections provide extra information about each script and its main purpose.
This script is used to automate the process of updating ArcDPS and its associated extensions. It will download the latest version of the following DLLs
- d3d9.dll - The ArcDPS dll
- d3d9_arcdps_buildtemplates.dll - The build templates extension
- d3d9_arcdps_extras.dll - The ArcDPS extras dll
- d3d9_arcdps_mechanics.dll - The ArcDPS mechanics extension
It downloads the DLLs into both the top level and \bin64 directories, as some Gw2 launch options change the path where the DLLs must be located. This makes the DLLs compatible with both normal launching and with launching via Gw2 Launch Buddy.
This script will upload EVTC log files to dps.report. It stores the last time that it ran in a JSON file, and will only upload new encounters since the last time it was run.
Additionally, extra data about each encounter is stored in the extra_upload_data directory. This includes the player list, success/failure, and boss ID. This data is used by the format-encounters.ps1 script in order to generate the report.
You must have configured at least one guild for the upload to work properly, as it will not upload encounters which are not associated with at least one guild in the configuration file.
The script will recursively scan the contents of the arcdps.cbtlogs folder, so it is not confused by the options to store encounters by guild or character name. It additionally can find either compressed or uncompressed logs.
The format-encounters.ps1 script will actually publish the encounters to the associated discord webhook URL. It will scan all the new EVTC data generated in the extra_upload_data directory, and create comments to post to the associated discord channel. Encounter lists will be separated by guild, and by day. The encounters will be sorted by time they were run. A header will be added which shows the guild name, date, and which wings were run. A footer is added which shows the players who ran in at least one encounter for that day.
This script may be useful to help configure the discord account mapping for a guild, rather than manually editing the configuration. It will run in the command prompt, and ask which guild to edit. It supports adding or removing players.
For more information about how to configure discord account ids, see configuring discord accounts.
This script is provided to configure the emoji mapping for a guild. It will ask for the emoji id of each boss. For more information about how to obtain these IDs, see configuring-emojis
This script is provided for users who previously had a v1 configuration which did not support multiple guilds. The old configuration format had all the guild-specific configurations stored at the top level of the configuration. This script will automatically convert the v1 configuration into the v2 configuration with a single guild. It should not be necessary to run this on a new installation.
This script is provided as a mechanism to run the update-arcdps.ps1 script, and then start Gw2 Launch Buddy.
This is a shared module file containing functions used by the scripts, and shoudl be kept at the root of the script installation.
This script is provided as a mechanism to load the module file along with the config object inside of a powershell session. The intent is to allow easier access to the module functions for custom usage such as manually uploading specific bosses. It's also useful for debugging purposes
This script contains tests for the simpleArcParse utility and is used during development to ensure proper functionality. It does not serve a purpose for general users.
The simpleArcParse utility is used by the upload-logs.ps1 script in order to extract useful information out of the EVTC encounter files. Primarily it is used to grab the player list, the boss name and id, and the success/failure status of the encounter.
It is not really a complete boss parser, and is instead intended to run very fast and extract the minimum information useful for uploading logs. It is written in C++
uploading to dps.report
The dps.report site does not use a formal account system. Currently the dps.report token is basically just a magic string which associates all the uploads to that string. You should set the dps_report_token to a random string, and keep it safe much like you would a password.
While there is a configure-v2-guilds.ps1 script, it is not intended to be used for general guild configuration.
You must configure at least one guild in order for upload-logs.ps1 and format-encounters.ps1 to work. If you were previously using a v1 configuration, there is a provided script to migrate to the v2 guilds format.
Guilds are used to tie encounters to specific discord webhooks. The list of guild members stored in the discord map is used for this purpose. An encounter will be considered as belonging to the guild which has the most members partaking in the encounter. In the case of ties, the priority number of the guild will be used to break the tie (lower numbers mean higher priority, with 1 being the highest priority guild).
You may configure a guild with a threshold. This is the minimum number of guild members who must participate in order for the encounter to be considered as that guild.
You may also configure whether a guild runs fractal encounters. If disabled, fractal encounters will not consider that guild when determining which guild ran an encounter.
It may be possible that an encounter does not belong to any configured guild. In this case, the encounter will simply be ignored. If you wish all encounters to be considered, add a guild with no players, a threshold of zero, and a low priority as a fallback.
If you wish to add a player as a guild member, even if they do not have a discord id, simply add them to the discord map, and set the contents to be the same as their gw2 username (or any other contents you wish to display in the player list, such as a nickname).
In order to show icons before boss names you must have server emojis enabled. Unfortunately there is no way for a webhook to include an image in the title sections, so emojis are required. You may opt out of using emojis by leaving the emoji map for a guild empty.
If you wish to configure emojis, you must determine the discord ID of the emoji you want to use for each boss.
To generate this text, type the emoji into one of the channels of your discord server, prefixed with a backslash. For example if your emoji is :kc: then type
This should show some text similar to
For each boss you want an icon, you must generate the id text and place it within the emoji map without the surrounding angle brackets. Previous versions of the scripts required unicode-escaped variants of '<' and '>', '\u003c' and '\u003e' respectivaly. Newer versions of the script will automatically insert the angle brackets for you.
configuring gw2 & discord accounts
The upload-logs.ps1 and format-encounters.ps1 scripts rely on the discord map to provide a list of players who are considered members of the guild. upload-logs.ps1 uses the account names to determine which encounters belong to which guilds.
To configure a successful discord map, you need to obtain the discord id for the account name on discord. This is done by obtaining the id for the @mention.
To generate this mention, you can enter their discord name into a message prefixed with a backslash.
For example, to generate the id for the account serenamyr#8942, you could type
into a discord channel. It should return text similar to
This text is the id of the particular mention. You should include this in the discord map hash table as the value for the matching gw2 account name. Do not include the surrounding angle brackets. Due to the way that configuration data is stored in JSON, this would require you to encode the brackets using unicode escape sequences. Newer versions of the script will automatically add missing angle brackets for you, preventing the need from using the escape sequences.
If you have questions, issues, or simply wish help in setting the scripts up, you may contact me in multiple ways. The easiest is to create a GitHub issue with details about the issue or bug.
You may also contact me on reddit at /u/platinummyr, or on discord at @serenamyr#8942. Finally, you can mail or PM me in Guild Wars 2 at "Serena Sedai.3064"