kandi background
Explore Kits

legendary | source replacement for the Epic Games Launcher | Game Engine library

 by   derrod Python Version: 0.20.25 License: GPL-3.0

 by   derrod Python Version: 0.20.25 License: GPL-3.0

Download this library from

kandi X-RAY | legendary Summary

legendary is a Python library typically used in Gaming, Game Engine, Electron applications. legendary has no bugs, it has no vulnerabilities, it has build file available, it has a Strong Copyleft License and it has medium support. You can install using 'pip install legendary' or download it from GitHub, PyPI.
Legendary - A free and open-source replacement for the Epic Games Launcher
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • legendary has a medium active ecosystem.
  • It has 2928 star(s) with 98 fork(s). There are 51 watchers for this library.
  • There were 10 major release(s) in the last 12 months.
  • There are 21 open issues and 277 have been closed. On average issues are closed in 28 days. There are 2 open pull requests and 0 closed requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of legendary is 0.20.25
legendary Support
Best in #Game Engine
Average in #Game Engine
legendary Support
Best in #Game Engine
Average in #Game Engine

quality kandi Quality

  • legendary has 0 bugs and 0 code smells.
legendary Quality
Best in #Game Engine
Average in #Game Engine
legendary Quality
Best in #Game Engine
Average in #Game Engine

securitySecurity

  • legendary has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • legendary code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
legendary Security
Best in #Game Engine
Average in #Game Engine
legendary Security
Best in #Game Engine
Average in #Game Engine

license License

  • legendary is licensed under the GPL-3.0 License. This license is Strong Copyleft.
  • Strong Copyleft licenses enforce sharing, and you can use them when creating open source projects.
legendary License
Best in #Game Engine
Average in #Game Engine
legendary License
Best in #Game Engine
Average in #Game Engine

buildReuse

  • legendary releases are available to install and integrate.
  • Deployable package is available in PyPI.
  • Build file is available. You can build the component from source.
  • Installation instructions, examples and code snippets are available.
legendary Reuse
Best in #Game Engine
Average in #Game Engine
legendary Reuse
Best in #Game Engine
Average in #Game Engine
Top functions reviewed by kandi - BETA

kandi has reviewed legendary and discovered the below as its top functions. This is intended to give you an instant insight into legendary implemented functionality, and help decide if they suit your requirements.

  • Main entry point .
  • Runs the analysis .
  • Show info .
  • Prepare download .
  • Run the worker .
  • Package a savegame .
  • Validate a list of files .
  • Generate aliases for a given game name .
  • Delete a list of files .
  • Query the registry for Windows Registry entries .

legendary Key Features

Legendary - A free and open-source replacement for the Epic Games Launcher

Python Package (any)

copy iconCopydownload iconDownload
pip install legendary-gl

Quickstart

copy iconCopydownload iconDownload
legendary auth

Usage

copy iconCopydownload iconDownload
usage: legendary [-h] [-H] [-v] [-y] [-V] [-J] [-A <seconds>] <command> ...

Legendary v0.X.X - "Codename"

optional arguments:
  -h, --help            show this help message and exit
  -H, --full-help       Show full help (including individual command help)
  -v, --debug           Set loglevel to debug
  -y, --yes             Default to yes for all prompts
  -V, --version         Print version and exit
  -J, --pretty-json     Pretty-print JSON
  -A <seconds>, --api-timeout <seconds>
                        API HTTP request timeout (default: 10 seconds)

Commands:
  <command>
    activate            Activate games on third party launchers
    alias               Manage aliases
    auth                Authenticate with the Epic Games Store
    clean-saves         Clean cloud saves
    cleanup             Remove old temporary, metadata, and manifest files
    crossover           Setup CrossOver for launching games (macOS only)
    download-saves      Download all cloud saves
    egl-sync            Setup or run Epic Games Launcher sync
    eos-overlay         Manage EOS Overlay install
    import              Import an already installed game
    info                Prints info about specified app name or manifest
    install (download, update, repair)
                        Install/download/update/repair a game
    launch              Launch a game
    list                List available (installable) games
    list-files          List files in manifest
    list-installed      List installed games
    list-saves          List available cloud saves
    move                Move specified app name to a new location
    status              Show legendary status information
    sync-saves          Sync cloud saves
    uninstall           Uninstall (delete) a game
    verify              Verify a game's local files

Individual command help:

Command: activate
usage: legendary activate [-h] (-U | -O)

optional arguments:
  -h, --help    show this help message and exit
  -U, --uplay   Activate Uplay/Ubisoft Connect titles on your Ubisoft account
                (Uplay install not required)
  -O, --origin  Activate Origin/EA App managed titles on your EA account
                (requires Origin to be installed)


Command: alias
usage: legendary alias [-h]
                       <add|rename|remove|list> [<App name/Old alias>]
                       [<New alias>]

positional arguments:
  <add|rename|remove|list>
                        Action: Add, rename, remove, or list alias(es)
  <App name/Old alias>  App name when using "add" or "list" action, existing
                        alias when using "rename" or "remove" action
  <New alias>           New alias when using "add" action

optional arguments:
  -h, --help            show this help message and exit


Command: auth
usage: legendary auth [-h] [--import] [--code <exchange code>]
                      [--sid <session id>] [--delete] [--disable-webview]

optional arguments:
  -h, --help            show this help message and exit
  --import              Import Epic Games Launcher authentication data (logs
                        out of EGL)
  --code <exchange code>
                        Use specified exchange code instead of interactive
                        authentication
  --sid <session id>    Use specified session id instead of interactive
                        authentication
  --delete              Remove existing authentication (log out)
  --disable-webview     Do not use embedded browser for login


Command: clean-saves
usage: legendary clean-saves [-h] [--delete-incomplete] [<App Name>]

positional arguments:
  <App Name>           Name of the app (optional)

optional arguments:
  -h, --help           show this help message and exit
  --delete-incomplete  Delete incomplete save files


Command: cleanup
usage: legendary cleanup [-h] [--keep-manifests]

optional arguments:
  -h, --help        show this help message and exit
  --keep-manifests  Do not delete old manifests


Command: crossover
usage: legendary crossover [-h] [--reset] [--download] [--ignore-version]
                           [--crossover-app <path to .app>]
                           [--crossover-bottle <bottle name>]
                           [<App Name>]

positional arguments:
  <App Name>            App name to configure, will configure defaults if
                        ommited

optional arguments:
  -h, --help            show this help message and exit
  --reset               Reset default/app-specific crossover configuration
  --download            Automatically download and set up a preconfigured
                        bottle (experimental)
  --ignore-version      Disable version check for available bottles when using
                        --download
  --crossover-app <path to .app>
                        Specify app to skip interactive selection
  --crossover-bottle <bottle name>
                        Specify bottle to skip interactive selection


Command: download-saves
usage: legendary download-saves [-h] [<App Name>]

positional arguments:
  <App Name>  Name of the app (optional)

optional arguments:
  -h, --help  show this help message and exit


Command: egl-sync
usage: legendary egl-sync [-h] [--egl-manifest-path EGL_MANIFEST_PATH]
                          [--egl-wine-prefix EGL_WINE_PREFIX] [--enable-sync]
                          [--disable-sync] [--one-shot] [--import-only]
                          [--export-only] [--migrate] [--unlink]

optional arguments:
  -h, --help            show this help message and exit
  --egl-manifest-path EGL_MANIFEST_PATH
                        Path to the Epic Games Launcher's Manifests folder,
                        should point to
                        /ProgramData/Epic/EpicGamesLauncher/Data/Manifests
  --egl-wine-prefix EGL_WINE_PREFIX
                        Path to the WINE prefix the Epic Games Launcher is
                        installed in
  --enable-sync         Enable automatic EGL <-> Legendary sync
  --disable-sync        Disable automatic sync and exit
  --one-shot            Sync once, do not ask to setup automatic sync
  --import-only         Only import games from EGL (no export)
  --export-only         Only export games to EGL (no import)
  --migrate             Import games into legendary, then remove them from EGL
                        (implies --import-only --one-shot --unlink)
  --unlink              Disable sync and remove EGL metadata from installed
                        games


Command: eos-overlay
usage: legendary eos-overlay [-h] [--path PATH] [--prefix PREFIX] [--app APP]
                             [--bottle BOTTLE]
                             <install|update|remove|enable|disable|info>

positional arguments:
  <install|update|remove|enable|disable|info>
                        Action: install, remove, enable, disable, or print
                        info about the overlay

optional arguments:
  -h, --help            show this help message and exit
  --path PATH           Path to the EOS overlay folder to be enabled/installed
                        to.
  --prefix PREFIX       WINE prefix to install the overlay in
  --app APP             Use this app's wine prefix (if configured in config)
  --bottle BOTTLE       WINE prefix to install the overlay in


Command: import
usage: legendary import [-h] [--disable-check] [--with-dlcs] [--skip-dlcs]
                        [--platform <Platform>]
                        <App Name> <Installation directory>

positional arguments:
  <App Name>            Name of the app
  <Installation directory>
                        Path where the game is installed

optional arguments:
  -h, --help            show this help message and exit
  --disable-check       Disables completeness check of the to-be-imported game
                        installation (useful if the imported game is a much
                        older version or missing files)
  --with-dlcs           Automatically attempt to import all DLCs with the base
                        game
  --skip-dlcs           Do not ask about importing DLCs.
  --platform <Platform>
                        Platform for import (default: Mac on macOS, otherwise
                        Windows)


Command: info
usage: legendary info [-h] [--offline] [--json] [--platform <Platform>]
                      <App Name/Manifest URI>

positional arguments:
  <App Name/Manifest URI>
                        App name or manifest path/URI

optional arguments:
  -h, --help            show this help message and exit
  --offline             Only print info available offline
  --json                Output information in JSON format
  --platform <Platform>
                        Platform to fetch info for (default: installed or Mac
                        on macOS, Windows otherwise)


Command: install
usage: legendary install <App Name> [options]

Aliases: download, update

positional arguments:
  <App Name>            Name of the app

optional arguments:
  -h, --help            show this help message and exit
  --base-path <path>    Path for game installations (defaults to ~/Games)
  --game-folder <path>  Folder for game installation (defaults to folder
                        specified in metadata)
  --max-shared-memory <size>
                        Maximum amount of shared memory to use (in MiB),
                        default: 1 GiB
  --max-workers <num>   Maximum amount of download workers, default: min(2 *
                        CPUs, 16)
  --manifest <uri>      Manifest URL or path to use instead of the CDN one
                        (e.g. for downgrading)
  --old-manifest <uri>  Manifest URL or path to use as the old one (e.g. for
                        testing patching)
  --delta-manifest <uri>
                        Manifest URL or path to use as the delta one (e.g. for
                        testing)
  --base-url <url>      Base URL to download from (e.g. to test or switch to a
                        different CDNs)
  --force               Download all files / ignore existing (overwrite)
  --disable-patching    Do not attempt to patch existing installation
                        (download entire changed files)
  --download-only, --no-install
                        Do not install app and do not run prerequisite
                        installers after download
  --update-only         Only update, do not do anything if specified app is
                        not installed
  --dlm-debug           Set download manager and worker processes' loglevel to
                        debug
  --platform <Platform>
                        Platform for install (default: installed or Windows)
  --prefix <prefix>     Only fetch files whose path starts with <prefix> (case
                        insensitive)
  --exclude <prefix>    Exclude files starting with <prefix> (case
                        insensitive)
  --install-tag <tag>   Only download files with the specified install tag
  --enable-reordering   Enable reordering optimization to reduce RAM
                        requirements during download (may have adverse results
                        for some titles)
  --dl-timeout <sec>    Connection timeout for downloader (default: 10
                        seconds)
  --save-path <path>    Set save game path to be used for sync-saves
  --repair              Repair installed game by checking and redownloading
                        corrupted/missing files
  --repair-and-update   Update game to the latest version when repairing
  --ignore-free-space   Do not abort if not enough free space is available
  --disable-delta-manifests
                        Do not use delta manifests when updating (may increase
                        download size)
  --reset-sdl           Reset selective downloading choices (requires repair
                        to download new components)
  --skip-sdl            Skip SDL prompt and continue with defaults (only
                        required game data)
  --disable-sdl         Disable selective downloading for title, reset
                        existing configuration (if any)
  --preferred-cdn <hostname>
                        Set the hostname of the preferred CDN to use when
                        available
  --no-https            Download games via plaintext HTTP (like EGS), e.g. for
                        use with a lan cache
  --with-dlcs           Automatically install all DLCs with the base game
  --skip-dlcs           Do not ask about installing DLCs.


Command: launch
usage: legendary launch <App Name> [options]

Note: additional arguments are passed to the game

positional arguments:
  <App Name>            Name of the app

optional arguments:
  -h, --help            show this help message and exit
  --offline             Skip login and launch game without online
                        authentication
  --skip-version-check  Skip version check when launching game in online mode
  --override-username <username>
                        Override username used when launching the game (only
                        works with some titles)
  --dry-run             Print the command line that would have been used to
                        launch the game and exit
  --language <two letter language code>
                        Override language for game launch (defaults to system
                        locale)
  --wrapper <wrapper command>
                        Wrapper command to launch game with
  --set-defaults        Save parameters used to launch to config (does not
                        include env vars)
  --reset-defaults      Reset config settings for app and exit
  --override-exe <exe path>
                        Override executable to launch (relative path)
  --origin              Launch Origin to activate or run the game.
  --json                Print launch information as JSON and exit
  --wine <wine binary>  Set WINE binary to use to launch the app
  --wine-prefix <wine pfx path>
                        Set WINE prefix to use
  --no-wine             Do not run game with WINE (e.g. if a wrapper is used)
  --crossover           Interactively configure CrossOver for this
                        application.
  --crossover-app <path to .app>
                        Specify which App to use for CrossOver (e.g.
                        "/Applications/CrossOver.app")
  --crossover-bottle <bottle name>
                        Specify which bottle to use for CrossOver


Command: list
usage: legendary list [-h] [--platform <Platform>] [--include-ue] [-T] [--csv]
                      [--tsv] [--json] [--force-refresh]

optional arguments:
  -h, --help            show this help message and exit
  --platform <Platform>
                        Platform to fetch game list for (default: Mac on
                        macOS, otherwise Windows)
  --include-ue          Also include Unreal Engine content
                        (Engine/Marketplace) in list
  -T, --third-party, --include-non-installable
                        Include apps that are not installable (e.g. that have
                        to be activated on Origin)
  --csv                 List games in CSV format
  --tsv                 List games in TSV format
  --json                List games in JSON format
  --force-refresh       Force a refresh of all game metadata


Command: list-files
usage: legendary list-files [-h] [--force-download] [--platform <Platform>]
                            [--manifest <uri>] [--csv] [--tsv] [--json]
                            [--hashlist] [--install-tag <tag>]
                            [<App Name>]

positional arguments:
  <App Name>            Name of the app (optional)

optional arguments:
  -h, --help            show this help message and exit
  --force-download      Always download instead of using on-disk manifest
  --platform <Platform>
                        Platform (default: Mac on macOS, otherwise Windows)
  --manifest <uri>      Manifest URL or path to use instead of the CDN one
  --csv                 Output in CSV format
  --tsv                 Output in TSV format
  --json                Output in JSON format
  --hashlist            Output file hash list in hashcheck/sha1sum -c
                        compatible format
  --install-tag <tag>   Show only files with specified install tag


Command: list-installed
usage: legendary list-installed [-h] [--check-updates] [--csv] [--tsv]
                                [--json] [--show-dirs]

optional arguments:
  -h, --help       show this help message and exit
  --check-updates  Check for updates for installed games
  --csv            List games in CSV format
  --tsv            List games in TSV format
  --json           List games in JSON format
  --show-dirs      Print installation directory in output


Command: list-saves
usage: legendary list-saves [-h] [<App Name>]

positional arguments:
  <App Name>  Name of the app (optional)

optional arguments:
  -h, --help  show this help message and exit


Command: move
usage: legendary move [-h] [--skip-move] <App Name> <New Base Path>

positional arguments:
  <App Name>       Name of the app
  <New Base Path>  Directory to move game folder to

optional arguments:
  -h, --help       show this help message and exit
  --skip-move      Only change legendary database, do not move files (e.g. if
                   already moved)


Command: status
usage: legendary status [-h] [--offline] [--json]

optional arguments:
  -h, --help  show this help message and exit
  --offline   Only print offline status information, do not login
  --json      Show status in JSON format


Command: sync-saves
usage: legendary sync-saves [-h] [--skip-upload] [--skip-download]
                            [--force-upload] [--force-download]
                            [--save-path <path>] [--disable-filters]
                            [<App Name>]

positional arguments:
  <App Name>          Name of the app (optional)

optional arguments:
  -h, --help          show this help message and exit
  --skip-upload       Only download new saves from cloud, don't upload
  --skip-download     Only upload new saves from cloud, don't download
  --force-upload      Force upload even if local saves are older
  --force-download    Force download even if local saves are newer
  --save-path <path>  Override savegame path (requires single app name to be
                      specified)
  --disable-filters   Disable save game file filtering


Command: uninstall
usage: legendary uninstall [-h] [--keep-files] <App Name>

positional arguments:
  <App Name>    Name of the app

optional arguments:
  -h, --help    show this help message and exit
  --keep-files  Keep files but remove game from Legendary database


Command: verify
usage: legendary verify [-h] <App Name>

positional arguments:
  <App Name>  Name of the app

optional arguments:
  -h, --help  show this help message and exit

Config file

copy iconCopydownload iconDownload
[Legendary]
log_level = debug
; maximum shared memory (in MiB) to use for installation
max_memory = 2048
; maximum number of worker processes when downloading (fewer workers will be slower, but also use less system resources)
max_workers = 8
; default install directory
install_dir = /mnt/tank/games
; locale override, must be in RFC 1766 format (e.g. "en-US")
locale = en-US
; whether or not syncing with egl is enabled
egl_sync = false
; path to the "Manifests" folder in the EGL ProgramData directory
egl_programdata = /home/user/Games/epic-games-store/drive_c/... 
; Set preferred CDN host (e.g. to improve download speed)
preferred_cdn = epicgames-download1.akamaized.net
; disable HTTPS for downloads (e.g. to use a LanCache)
disable_https = false
; Disables the automatic update check
disable_update_check = false
; Disables the notice about an available update on exit
disable_update_notice = false
; Disable automatically-generated aliases
disable_auto_aliasing = false

; macOS specific settings
; Default application platform to use (default: Mac on macOS, Windows elsewhere)
default_platform = Windows
; Fallback to "Windows" platform if native version unavailable
install_platform_fallback = true
; (macOS) Disable automatic CrossOver use
disable_auto_crossover = false
; Default directory for native Mac applications (.app packages)
mac_install_dir = /User/legendary/Applications

[Legendary.aliases]
; List of aliases for simpler CLI use, in the format `<alias> = <app name>`
HITMAN 3 = Eider
gtav = 9d2d0eb64d5c44529cece33fe2a46482

; default settings to use for all apps (unless overridden in the app's config section)
; Note that only the settings listed below are supported.
[default]
; (all) wrapper to run the game with (e.g. "gamemode")
wrapper = gamemode
; (linux/macOS) Wine executable and prefix
wine_executable = wine
wine_prefix = /home/user/.wine
; (macOS) CrossOver options
crossover_app = /Applications/CrossOver.app
crossover_bottle = Legendary

; default environment variables to set (overridden by game specific ones)
[default.env]
WINEPREFIX = /home/user/legendary/.wine

; Settings to only use for "AppName"
[AppName]
; launch game without online authentication by default
offline = true
; Skip checking for updates when launching this game
skip_update_check = true
; start parameters to use (in addition to the required ones)
start_params = -windowed
; override language with two-letter language code
language = fr
; Override Wine version for this app
wine_executable = /path/to/wine64

[AppName.env]
; environment variables to set for this game (mostly useful on linux)
WINEPREFIX = /mnt/tank/games/Game/.wine
DXVK_CONFIG_FILE = /mnt/tank/games/Game/dxvk.conf

[AppName2]
; Use a wrapper to run this script
; Note that the path might have to be quoted if it contains spaces
wrapper = "/path/with spaces/gamemoderun"
; Do not run this executable with WINE (e.g. when the wrapper handles that)
no_wine = true
; Override the executable launched for this game, for example to bypass a launcher (e.g. Borderlands)
override_exe = relative/path/to/file.exe
; Disable selective downloading for this title
disable_sdl = true

[AppName3]
; Command to run before launching the gmae
pre_launch_command = /path/to/script.sh
; Whether or not to wait for command to finish running
pre_launch_wait = false
; (macOS) override crossover settings
crossover_app = /Applications/CrossOver Nightly.app
crossover_bottle = SomethingElse

Deserializing JSON to a Dictionary<string, Item> with Item being abstract

copy iconCopydownload iconDownload
public abstract class Item
{
    public virtual ItemType Type => ItemType.NONE; // expression-bodied property

    public enum ItemType
    {
        NONE,
        WEAPON,
        ARMOUR,
        CONSUMABLE,
    }
}

public class Weapon : Item
{
    public override ItemType Type => ItemType.WEAPON; // expression-bodied property
    public string SomeWeaponProperty { get; set; }
}
public class ItemConverter : JsonConverter<Item>
{
    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer, Item? value, JsonSerializer serializer) => throw new NotImplementedException();

    public override Item ReadJson(JsonReader reader, Type objectType, Item existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // TODO handle nulls
        var jObject = JObject.Load(reader);
        Item result;
        switch (jObject.GetValue("type", StringComparison.InvariantCultureIgnoreCase).ToObject<Item.ItemType>(serializer))
        {
            case Item.ItemType.WEAPON:
                result = jObject.ToObject<Weapon>();
                break;
            // handle other types
            // case Item.ItemType.ARMOUR: 
            // case Item.ItemType.CONSUMABLE:
            case Item.ItemType.NONE:
            default:
                throw new ArgumentOutOfRangeException();
        }

        return result;
    }
}
var item = new Weapon();
var settings = new JsonSerializerSettings
{
    Converters = { new ItemConverter() }
};
string json = JsonConvert.SerializeObject(item, settings);
var res = JsonConvert.DeserializeObject<Item>(json, settings);

Console.WriteLine(res.GetType()); // prints Weapon
-----------------------
public abstract class Item
{
    public virtual ItemType Type => ItemType.NONE; // expression-bodied property

    public enum ItemType
    {
        NONE,
        WEAPON,
        ARMOUR,
        CONSUMABLE,
    }
}

public class Weapon : Item
{
    public override ItemType Type => ItemType.WEAPON; // expression-bodied property
    public string SomeWeaponProperty { get; set; }
}
public class ItemConverter : JsonConverter<Item>
{
    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer, Item? value, JsonSerializer serializer) => throw new NotImplementedException();

    public override Item ReadJson(JsonReader reader, Type objectType, Item existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // TODO handle nulls
        var jObject = JObject.Load(reader);
        Item result;
        switch (jObject.GetValue("type", StringComparison.InvariantCultureIgnoreCase).ToObject<Item.ItemType>(serializer))
        {
            case Item.ItemType.WEAPON:
                result = jObject.ToObject<Weapon>();
                break;
            // handle other types
            // case Item.ItemType.ARMOUR: 
            // case Item.ItemType.CONSUMABLE:
            case Item.ItemType.NONE:
            default:
                throw new ArgumentOutOfRangeException();
        }

        return result;
    }
}
var item = new Weapon();
var settings = new JsonSerializerSettings
{
    Converters = { new ItemConverter() }
};
string json = JsonConvert.SerializeObject(item, settings);
var res = JsonConvert.DeserializeObject<Item>(json, settings);

Console.WriteLine(res.GetType()); // prints Weapon
-----------------------
public abstract class Item
{
    public virtual ItemType Type => ItemType.NONE; // expression-bodied property

    public enum ItemType
    {
        NONE,
        WEAPON,
        ARMOUR,
        CONSUMABLE,
    }
}

public class Weapon : Item
{
    public override ItemType Type => ItemType.WEAPON; // expression-bodied property
    public string SomeWeaponProperty { get; set; }
}
public class ItemConverter : JsonConverter<Item>
{
    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer, Item? value, JsonSerializer serializer) => throw new NotImplementedException();

    public override Item ReadJson(JsonReader reader, Type objectType, Item existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // TODO handle nulls
        var jObject = JObject.Load(reader);
        Item result;
        switch (jObject.GetValue("type", StringComparison.InvariantCultureIgnoreCase).ToObject<Item.ItemType>(serializer))
        {
            case Item.ItemType.WEAPON:
                result = jObject.ToObject<Weapon>();
                break;
            // handle other types
            // case Item.ItemType.ARMOUR: 
            // case Item.ItemType.CONSUMABLE:
            case Item.ItemType.NONE:
            default:
                throw new ArgumentOutOfRangeException();
        }

        return result;
    }
}
var item = new Weapon();
var settings = new JsonSerializerSettings
{
    Converters = { new ItemConverter() }
};
string json = JsonConvert.SerializeObject(item, settings);
var res = JsonConvert.DeserializeObject<Item>(json, settings);

Console.WriteLine(res.GetType()); // prints Weapon
-----------------------
public class ItemCreationConvertor : JsonConverter
{
    private readonly Dictionary<Item.ItemType, Type> map = new Dictionary<Item.ItemType, Type>
    {
        {Item.ItemType.WEAPON, typeof(Weapon)},
        {Item.ItemType.NONE, typeof(Item)}
    };

    public override bool CanWrite => false;

    public override bool CanConvert(Type objectType) => typeof(Item).IsAssignableFrom(objectType);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        // Load JObject from stream
        var jObject = JObject.Load(reader);

        // Create target object based on JObject
        Type targetObjectType = objectType;

        if (jObject["itemType"] != null)
        {
            targetObjectType = this.map.TryGetValue((Item.ItemType)(int)(jObject["itemType"]), out targetObjectType) ? targetObjectType : objectType;
            // return new Weapon();
        }

        object target = Activator.CreateInstance(targetObjectType);

        // Populate the object properties
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
Dictionary<string, Item> items = new Dictionary<string, Item>();
items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json, new JsonSerializerSettings
{
    Converters = new List<JsonConverter> {new ItemCreationConvertor()}
});
[Newtonsoft.Json.JsonConverter(typeof(ItemCreationConvertor))]
public class Item
{
    // Other properties go here
}

items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(testJson2);
-----------------------
public class ItemCreationConvertor : JsonConverter
{
    private readonly Dictionary<Item.ItemType, Type> map = new Dictionary<Item.ItemType, Type>
    {
        {Item.ItemType.WEAPON, typeof(Weapon)},
        {Item.ItemType.NONE, typeof(Item)}
    };

    public override bool CanWrite => false;

    public override bool CanConvert(Type objectType) => typeof(Item).IsAssignableFrom(objectType);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        // Load JObject from stream
        var jObject = JObject.Load(reader);

        // Create target object based on JObject
        Type targetObjectType = objectType;

        if (jObject["itemType"] != null)
        {
            targetObjectType = this.map.TryGetValue((Item.ItemType)(int)(jObject["itemType"]), out targetObjectType) ? targetObjectType : objectType;
            // return new Weapon();
        }

        object target = Activator.CreateInstance(targetObjectType);

        // Populate the object properties
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
Dictionary<string, Item> items = new Dictionary<string, Item>();
items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json, new JsonSerializerSettings
{
    Converters = new List<JsonConverter> {new ItemCreationConvertor()}
});
[Newtonsoft.Json.JsonConverter(typeof(ItemCreationConvertor))]
public class Item
{
    // Other properties go here
}

items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(testJson2);
-----------------------
public class ItemCreationConvertor : JsonConverter
{
    private readonly Dictionary<Item.ItemType, Type> map = new Dictionary<Item.ItemType, Type>
    {
        {Item.ItemType.WEAPON, typeof(Weapon)},
        {Item.ItemType.NONE, typeof(Item)}
    };

    public override bool CanWrite => false;

    public override bool CanConvert(Type objectType) => typeof(Item).IsAssignableFrom(objectType);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        // Load JObject from stream
        var jObject = JObject.Load(reader);

        // Create target object based on JObject
        Type targetObjectType = objectType;

        if (jObject["itemType"] != null)
        {
            targetObjectType = this.map.TryGetValue((Item.ItemType)(int)(jObject["itemType"]), out targetObjectType) ? targetObjectType : objectType;
            // return new Weapon();
        }

        object target = Activator.CreateInstance(targetObjectType);

        // Populate the object properties
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
Dictionary<string, Item> items = new Dictionary<string, Item>();
items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json, new JsonSerializerSettings
{
    Converters = new List<JsonConverter> {new ItemCreationConvertor()}
});
[Newtonsoft.Json.JsonConverter(typeof(ItemCreationConvertor))]
public class Item
{
    // Other properties go here
}

items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(testJson2);

Output all results of findstr to seperate txt files

copy iconCopydownload iconDownload
for /f "tokens=1,* delims=:" %%S in ('findstr /i "echo" "%~f0"^|findstr /n /i "echo" ') do ECHO %%T>"U:\moreresults\result%%S.txt"
-----------------------
@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion
Set "i=0"
For /F Delims^=^ EOL^= %%G In (
    '%SystemRoot%\System32\find.exe /I "Starfy" 0^<".\List.txt" 2^>NUL'
) Do (
    Set /A i += 1
    1>"Result!i!.txt" Echo %%G 
)
-----------------------
@echo off

for /F "tokens=1* delims=:" %%a in ('findstr "Starfy" .\List.txt ^| findstr /N "^"') do >result%%a.txt echo %%b

Getting unexpected fault address error when unmarshalling json from bolt database in external function

copy iconCopydownload iconDownload
charList = append(charList, v)
vc := make([]byte, len(v))
copy(vc,v)
charList = append(charList, vc)
-----------------------
charList = append(charList, v)
vc := make([]byte, len(v))
copy(vc,v)
charList = append(charList, vc)

Changing many same class DIV's color based on response value

copy iconCopydownload iconDownload
//Daily offers
fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.daily.entries, function(i, item) {
            if (data.data.daily.entries[i].bundle != null) {
                return;
            }
            var html='';
            if(item.items[0].rarity.displayValue){
              var bgcolorforDiv=fetchbackGround(item.items[0].rarity.displayValue);
              html='<div class="card" style="background-color:'+bgcolorforDiv+'"> <b>' + item.items[0].name + '</b> <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + ' <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>';

            }
            else{
              html='<div class="card"> <b>' + item.items[0].name + '</b> <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + ' <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>';
            }
            $('body > #cards_daily').append(html);
        });
    });
function fetchbackGround(rarity){
  var background="rgb(148, 148, 150)";
  switch(rarity){
     case "rare":background="red";break;
     case "Uncommon":background="#319236";break;
     case "Rare":background="#4c51f7";break;
     case "Epic":background="#9d4dbb";break;
     case "Legendary":background="#f3af19";break;
     case "Icon Series":background="#00FFFF";break;
  }
  return background;
}
//Featured offers
fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.featured.entries, function(i, item) {
            if (data.data.featured.entries[i].bundle != null) {
                return;
            }
            $('body > #cards_featured').append('<div class="card"> ' + item.items[0].name + ' <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + '  <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>');
        });
    });

fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.specialFeatured.entries, function(i, item) {
            if (data.data.specialFeatured.entries[i].bundle != null) {
                return;
            }
            $('body > #cards_featured_special').append('<div class="card"> ' + item.items[0].name + ' <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + '  <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>');
        });
    });

//Timer
(function() {
    var start = new Date;
    start.setHours(2, 0, 0); // 02.00

    function pad(num) {
        return ("0" + parseInt(num)).substr(-2);
    }

    function tick() {
        var now = new Date;
        if (now > start) { // too late, go to tomorrow
            start.setDate(start.getDate() + 1);
        }
        var remain = ((start - now) / 1000);
        var hh = pad((remain / 60 / 60) % 60);
        var mm = pad((remain / 60) % 60);
        var ss = pad(remain % 60);
        document.getElementById('time').innerHTML =
            hh + ":" + mm + ":" + ss;
        setTimeout(tick, 1000);
    }
    document.addEventListener('DOMContentLoaded', tick);
}());
@import url('https://fonts.googleapis.com/css2?family=Indie+Flower&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Road+Rage&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

body {
    background-color: rgb(42, 42, 184);
    display: flex;
    align-items: center;
    flex-direction: column;
}

header {
    font-family: 'Road Rage', Arial;
    font-size: 30px;
    height: 100px;
    text-align: center;
}

#cards_daily {
    margin-top: 160px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#cards_featured {
    margin-top: 100px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#cards_featured_special {
    margin-top: 100px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#OTSIKKO {
    font-family: 'Road Rage', Arial;
    position: absolute;
    font-size: 3rem;
    top: -40px;
    left: 0;
    right: 0;
    margin: 0 auto;
    color: yellow;
    background-color: rgb(105, 105, 105);
    width: max-content;
    padding: 0px 10px 10px;
    border-radius: 10px;
}

.timer {
    font-family: 'Monospace', Arial;
    position: absolute;
    font-size: 15px;
    top: 10px;
    left: 0;
    right: 0;
    margin: 0 auto;
    color: yellow;
    /*background-color: rgb(105, 105, 105);*/
    width: 290px;
    padding: 5px 5px 10px;
    border-radius: 10px 10px 0px 0px;
    text-align: center;
    display: block;
    font-weight: 700;
}

.card {
    display: flex;
    background-color: rgb(148, 148, 150);
    width: 160px;
    height: 240px;
    border-radius: 15px;
    padding: 0px 10px;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    color: white;
    font-family: 'Poppins', Arial;
    font-size: 1rem;
    margin: 15px 10px;
    -webkit-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    -moz-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    text-align: center;
    overflow: hidden;
}

.card span {
    display: flex;
    height: 30px;
    align-items: center;
}

#v_buck {
    margin-left: 5px;
}

#image {
    /*DEBUG BORDER
border: 4px solid red; */
    max-height: 125px;
}

#introduce,
#introduce1 {
    font-size: 10px;
    color: rgb(82, 82, 87);
}

footer {
    padding: 10px;
    font-family: 'Indie Flower', Helvetica, sans-serif;
    text-align: center;
    text-decoration: none;
    color: white;
}

footer a {
    text-decoration: none;
    color: white;
}


/*DESKTOP*/

@media only screen and (min-width: 768px) {
    * {
        padding: 0;
        margin: 0;
        box-sizing: border-box;
    }
    body {
        background-color: rgb(82, 82, 87);
        display: flex;
        align-items: center;
        flex-direction: column;
    }
    header {
        font-family: 'Road Rage', Arial;
        font-size: 45px;
        height: 100px;
        text-align: center;
    }
    #cards_daily {
        margin-top: 150px;
        display: flex;
        justify-content: space-evenly;
        align-items: center;
        background-color: rgb(105, 105, 105);
        padding: 30px;
        width: 90%;
        max-width: 1740px;
        border-radius: 15px;
        position: relative;
        flex-wrap: wrap;
    }
    #cards_featured {
        margin-top: 100px;
        margin-bottom: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        background-color: rgb(105, 105, 105);
        padding: 30px 10px;
        width: 90%;
        max-width: 1740px;
        max-height: max-content;
        border-radius: 15px;
        position: relative;
    }
    #cards_featured_special {
        margin-top: 100px;
        margin-bottom: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        background-color: rgb(105, 105, 105);
        padding: 30px 10px;
        width: 90%;
        max-width: 1740px;
        max-height: max-content;
        border-radius: 15px;
        position: relative;
    }
    #OTSIKKO {
        font-family: 'Road Rage', Arial;
        position: absolute;
        font-size: 45px;
        top: -65px;
        left: 0px;
        color: yellow;
        background-color: rgb(105, 105, 105);
        width: max-content;
        padding: 0px 10px 10px;
        border-radius: 10px;
    }
    .timer {
        font-family: 'Monospace', Arial;
        position: absolute;
        font-size: 15px;
        top: -20px;
        right: 0px;
        color: yellow;
        background-color: rgb(105, 105, 105);
        width: 290px;
        padding: 5px 5px 10px;
        border-radius: 10px 10px 0px 0px;
        text-align: center;
        display: block;
        font-weight: 700;
    }
    .card {
        display: flex;
        background-color: rgb(148, 148, 150);
        width: 230px;
        height: 340px;
        border-radius: 15px;
        padding: 0px 10px;
        flex-direction: column;
        justify-content: space-between;
        align-items: center;
        color: white;
        font-family: 'Poppins', Arial;
        font-size: 22px;
        margin: 15px 10px;
        -webkit-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        -moz-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        text-align: center;
        overflow: hidden;
    }
    .card span {
        display: flex;
        height: 30px;
        align-items: center;
    }
    #v_buck {
        margin-left: 5px;
    }
    #image {
        /*DEBUG BORDER
    border: 4px solid red; */
        max-height: 250px;
    }
    #introduce,
    #introduce1 {
        font-size: 10px;
        color: rgb(82, 82, 87);
    }
    footer {
        padding: 10px;
        font-family: 'Indie Flower', Helvetica, sans-serif;
        text-align: center;
        text-decoration: none;
        color: white;
    }
    footer a {
        text-decoration: none;
        color: white;
    }
}
<!DOCTYPE html>
<html>

<head>

    <title>Fortnite itemshop tracker!</title>
<style type="text/css">

</style>
    <link rel="stylesheet" href="style.css?v=1.0">
    <link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
    <link rel="manifest" href="img/site.webmanifest">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

</head>

<body>


    <header>
        <h1>Pinja's daily itemshop tracker</h1>
        <h3>[Work in progress]</h3>
    </header>
    <div id="cards_daily">

        <H1 id="OTSIKKO">Daily offers</H1>
        <div class="timer">
            Daily shop reset in: <span id="time"></span>
        </div>


    </div>
    <div id="cards_featured_special">
        <H1 id="OTSIKKO">Featured specials</H1>
        <div class="timer">
            Bundles are not included!
        </div>

    </div>
    <div id="cards_featured">
        <H1 id="OTSIKKO">Featured</H1>
        <div class="timer">
            Bundles are not included!
        </div>

    </div>
</body>

</html>
-----------------------
//Daily offers
fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.daily.entries, function(i, item) {
            if (data.data.daily.entries[i].bundle != null) {
                return;
            }
            var html='';
            if(item.items[0].rarity.displayValue){
              var bgcolorforDiv=fetchbackGround(item.items[0].rarity.displayValue);
              html='<div class="card" style="background-color:'+bgcolorforDiv+'"> <b>' + item.items[0].name + '</b> <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + ' <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>';

            }
            else{
              html='<div class="card"> <b>' + item.items[0].name + '</b> <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + ' <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>';
            }
            $('body > #cards_daily').append(html);
        });
    });
function fetchbackGround(rarity){
  var background="rgb(148, 148, 150)";
  switch(rarity){
     case "rare":background="red";break;
     case "Uncommon":background="#319236";break;
     case "Rare":background="#4c51f7";break;
     case "Epic":background="#9d4dbb";break;
     case "Legendary":background="#f3af19";break;
     case "Icon Series":background="#00FFFF";break;
  }
  return background;
}
//Featured offers
fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.featured.entries, function(i, item) {
            if (data.data.featured.entries[i].bundle != null) {
                return;
            }
            $('body > #cards_featured').append('<div class="card"> ' + item.items[0].name + ' <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + '  <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>');
        });
    });

fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.specialFeatured.entries, function(i, item) {
            if (data.data.specialFeatured.entries[i].bundle != null) {
                return;
            }
            $('body > #cards_featured_special').append('<div class="card"> ' + item.items[0].name + ' <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + '  <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>');
        });
    });

//Timer
(function() {
    var start = new Date;
    start.setHours(2, 0, 0); // 02.00

    function pad(num) {
        return ("0" + parseInt(num)).substr(-2);
    }

    function tick() {
        var now = new Date;
        if (now > start) { // too late, go to tomorrow
            start.setDate(start.getDate() + 1);
        }
        var remain = ((start - now) / 1000);
        var hh = pad((remain / 60 / 60) % 60);
        var mm = pad((remain / 60) % 60);
        var ss = pad(remain % 60);
        document.getElementById('time').innerHTML =
            hh + ":" + mm + ":" + ss;
        setTimeout(tick, 1000);
    }
    document.addEventListener('DOMContentLoaded', tick);
}());
@import url('https://fonts.googleapis.com/css2?family=Indie+Flower&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Road+Rage&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

body {
    background-color: rgb(42, 42, 184);
    display: flex;
    align-items: center;
    flex-direction: column;
}

header {
    font-family: 'Road Rage', Arial;
    font-size: 30px;
    height: 100px;
    text-align: center;
}

#cards_daily {
    margin-top: 160px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#cards_featured {
    margin-top: 100px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#cards_featured_special {
    margin-top: 100px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#OTSIKKO {
    font-family: 'Road Rage', Arial;
    position: absolute;
    font-size: 3rem;
    top: -40px;
    left: 0;
    right: 0;
    margin: 0 auto;
    color: yellow;
    background-color: rgb(105, 105, 105);
    width: max-content;
    padding: 0px 10px 10px;
    border-radius: 10px;
}

.timer {
    font-family: 'Monospace', Arial;
    position: absolute;
    font-size: 15px;
    top: 10px;
    left: 0;
    right: 0;
    margin: 0 auto;
    color: yellow;
    /*background-color: rgb(105, 105, 105);*/
    width: 290px;
    padding: 5px 5px 10px;
    border-radius: 10px 10px 0px 0px;
    text-align: center;
    display: block;
    font-weight: 700;
}

.card {
    display: flex;
    background-color: rgb(148, 148, 150);
    width: 160px;
    height: 240px;
    border-radius: 15px;
    padding: 0px 10px;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    color: white;
    font-family: 'Poppins', Arial;
    font-size: 1rem;
    margin: 15px 10px;
    -webkit-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    -moz-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    text-align: center;
    overflow: hidden;
}

.card span {
    display: flex;
    height: 30px;
    align-items: center;
}

#v_buck {
    margin-left: 5px;
}

#image {
    /*DEBUG BORDER
border: 4px solid red; */
    max-height: 125px;
}

#introduce,
#introduce1 {
    font-size: 10px;
    color: rgb(82, 82, 87);
}

footer {
    padding: 10px;
    font-family: 'Indie Flower', Helvetica, sans-serif;
    text-align: center;
    text-decoration: none;
    color: white;
}

footer a {
    text-decoration: none;
    color: white;
}


/*DESKTOP*/

@media only screen and (min-width: 768px) {
    * {
        padding: 0;
        margin: 0;
        box-sizing: border-box;
    }
    body {
        background-color: rgb(82, 82, 87);
        display: flex;
        align-items: center;
        flex-direction: column;
    }
    header {
        font-family: 'Road Rage', Arial;
        font-size: 45px;
        height: 100px;
        text-align: center;
    }
    #cards_daily {
        margin-top: 150px;
        display: flex;
        justify-content: space-evenly;
        align-items: center;
        background-color: rgb(105, 105, 105);
        padding: 30px;
        width: 90%;
        max-width: 1740px;
        border-radius: 15px;
        position: relative;
        flex-wrap: wrap;
    }
    #cards_featured {
        margin-top: 100px;
        margin-bottom: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        background-color: rgb(105, 105, 105);
        padding: 30px 10px;
        width: 90%;
        max-width: 1740px;
        max-height: max-content;
        border-radius: 15px;
        position: relative;
    }
    #cards_featured_special {
        margin-top: 100px;
        margin-bottom: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        background-color: rgb(105, 105, 105);
        padding: 30px 10px;
        width: 90%;
        max-width: 1740px;
        max-height: max-content;
        border-radius: 15px;
        position: relative;
    }
    #OTSIKKO {
        font-family: 'Road Rage', Arial;
        position: absolute;
        font-size: 45px;
        top: -65px;
        left: 0px;
        color: yellow;
        background-color: rgb(105, 105, 105);
        width: max-content;
        padding: 0px 10px 10px;
        border-radius: 10px;
    }
    .timer {
        font-family: 'Monospace', Arial;
        position: absolute;
        font-size: 15px;
        top: -20px;
        right: 0px;
        color: yellow;
        background-color: rgb(105, 105, 105);
        width: 290px;
        padding: 5px 5px 10px;
        border-radius: 10px 10px 0px 0px;
        text-align: center;
        display: block;
        font-weight: 700;
    }
    .card {
        display: flex;
        background-color: rgb(148, 148, 150);
        width: 230px;
        height: 340px;
        border-radius: 15px;
        padding: 0px 10px;
        flex-direction: column;
        justify-content: space-between;
        align-items: center;
        color: white;
        font-family: 'Poppins', Arial;
        font-size: 22px;
        margin: 15px 10px;
        -webkit-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        -moz-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        text-align: center;
        overflow: hidden;
    }
    .card span {
        display: flex;
        height: 30px;
        align-items: center;
    }
    #v_buck {
        margin-left: 5px;
    }
    #image {
        /*DEBUG BORDER
    border: 4px solid red; */
        max-height: 250px;
    }
    #introduce,
    #introduce1 {
        font-size: 10px;
        color: rgb(82, 82, 87);
    }
    footer {
        padding: 10px;
        font-family: 'Indie Flower', Helvetica, sans-serif;
        text-align: center;
        text-decoration: none;
        color: white;
    }
    footer a {
        text-decoration: none;
        color: white;
    }
}
<!DOCTYPE html>
<html>

<head>

    <title>Fortnite itemshop tracker!</title>
<style type="text/css">

</style>
    <link rel="stylesheet" href="style.css?v=1.0">
    <link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
    <link rel="manifest" href="img/site.webmanifest">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

</head>

<body>


    <header>
        <h1>Pinja's daily itemshop tracker</h1>
        <h3>[Work in progress]</h3>
    </header>
    <div id="cards_daily">

        <H1 id="OTSIKKO">Daily offers</H1>
        <div class="timer">
            Daily shop reset in: <span id="time"></span>
        </div>


    </div>
    <div id="cards_featured_special">
        <H1 id="OTSIKKO">Featured specials</H1>
        <div class="timer">
            Bundles are not included!
        </div>

    </div>
    <div id="cards_featured">
        <H1 id="OTSIKKO">Featured</H1>
        <div class="timer">
            Bundles are not included!
        </div>

    </div>
</body>

</html>
-----------------------
//Daily offers
fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.daily.entries, function(i, item) {
            if (data.data.daily.entries[i].bundle != null) {
                return;
            }
            var html='';
            if(item.items[0].rarity.displayValue){
              var bgcolorforDiv=fetchbackGround(item.items[0].rarity.displayValue);
              html='<div class="card" style="background-color:'+bgcolorforDiv+'"> <b>' + item.items[0].name + '</b> <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + ' <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>';

            }
            else{
              html='<div class="card"> <b>' + item.items[0].name + '</b> <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + ' <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>';
            }
            $('body > #cards_daily').append(html);
        });
    });
function fetchbackGround(rarity){
  var background="rgb(148, 148, 150)";
  switch(rarity){
     case "rare":background="red";break;
     case "Uncommon":background="#319236";break;
     case "Rare":background="#4c51f7";break;
     case "Epic":background="#9d4dbb";break;
     case "Legendary":background="#f3af19";break;
     case "Icon Series":background="#00FFFF";break;
  }
  return background;
}
//Featured offers
fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.featured.entries, function(i, item) {
            if (data.data.featured.entries[i].bundle != null) {
                return;
            }
            $('body > #cards_featured').append('<div class="card"> ' + item.items[0].name + ' <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + '  <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>');
        });
    });

fetch('https://fortnite-api.com/v2/shop/br')
    .then(res => res.json())
    .then(data => {
        $.each(data.data.specialFeatured.entries, function(i, item) {
            if (data.data.specialFeatured.entries[i].bundle != null) {
                return;
            }
            $('body > #cards_featured_special').append('<div class="card"> ' + item.items[0].name + ' <br> <span>' + item.finalPrice + '<img id="v_buck" src="https://fortnite-api.com/images/vbuck.png" height="28px"> </span>' + '  <br> ' + '<img id="image" src="' + item.items[0].images.icon + '"></img>' + '</div>');
        });
    });

//Timer
(function() {
    var start = new Date;
    start.setHours(2, 0, 0); // 02.00

    function pad(num) {
        return ("0" + parseInt(num)).substr(-2);
    }

    function tick() {
        var now = new Date;
        if (now > start) { // too late, go to tomorrow
            start.setDate(start.getDate() + 1);
        }
        var remain = ((start - now) / 1000);
        var hh = pad((remain / 60 / 60) % 60);
        var mm = pad((remain / 60) % 60);
        var ss = pad(remain % 60);
        document.getElementById('time').innerHTML =
            hh + ":" + mm + ":" + ss;
        setTimeout(tick, 1000);
    }
    document.addEventListener('DOMContentLoaded', tick);
}());
@import url('https://fonts.googleapis.com/css2?family=Indie+Flower&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Road+Rage&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

body {
    background-color: rgb(42, 42, 184);
    display: flex;
    align-items: center;
    flex-direction: column;
}

header {
    font-family: 'Road Rage', Arial;
    font-size: 30px;
    height: 100px;
    text-align: center;
}

#cards_daily {
    margin-top: 160px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#cards_featured {
    margin-top: 100px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#cards_featured_special {
    margin-top: 100px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    background-color: rgb(105, 105, 105);
    padding: 30px 5px;
    width: 100%;
    max-width: 1740px;
    border-radius: 15px;
    position: relative;
    flex-wrap: wrap;
}

#OTSIKKO {
    font-family: 'Road Rage', Arial;
    position: absolute;
    font-size: 3rem;
    top: -40px;
    left: 0;
    right: 0;
    margin: 0 auto;
    color: yellow;
    background-color: rgb(105, 105, 105);
    width: max-content;
    padding: 0px 10px 10px;
    border-radius: 10px;
}

.timer {
    font-family: 'Monospace', Arial;
    position: absolute;
    font-size: 15px;
    top: 10px;
    left: 0;
    right: 0;
    margin: 0 auto;
    color: yellow;
    /*background-color: rgb(105, 105, 105);*/
    width: 290px;
    padding: 5px 5px 10px;
    border-radius: 10px 10px 0px 0px;
    text-align: center;
    display: block;
    font-weight: 700;
}

.card {
    display: flex;
    background-color: rgb(148, 148, 150);
    width: 160px;
    height: 240px;
    border-radius: 15px;
    padding: 0px 10px;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    color: white;
    font-family: 'Poppins', Arial;
    font-size: 1rem;
    margin: 15px 10px;
    -webkit-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    -moz-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
    text-align: center;
    overflow: hidden;
}

.card span {
    display: flex;
    height: 30px;
    align-items: center;
}

#v_buck {
    margin-left: 5px;
}

#image {
    /*DEBUG BORDER
border: 4px solid red; */
    max-height: 125px;
}

#introduce,
#introduce1 {
    font-size: 10px;
    color: rgb(82, 82, 87);
}

footer {
    padding: 10px;
    font-family: 'Indie Flower', Helvetica, sans-serif;
    text-align: center;
    text-decoration: none;
    color: white;
}

footer a {
    text-decoration: none;
    color: white;
}


/*DESKTOP*/

@media only screen and (min-width: 768px) {
    * {
        padding: 0;
        margin: 0;
        box-sizing: border-box;
    }
    body {
        background-color: rgb(82, 82, 87);
        display: flex;
        align-items: center;
        flex-direction: column;
    }
    header {
        font-family: 'Road Rage', Arial;
        font-size: 45px;
        height: 100px;
        text-align: center;
    }
    #cards_daily {
        margin-top: 150px;
        display: flex;
        justify-content: space-evenly;
        align-items: center;
        background-color: rgb(105, 105, 105);
        padding: 30px;
        width: 90%;
        max-width: 1740px;
        border-radius: 15px;
        position: relative;
        flex-wrap: wrap;
    }
    #cards_featured {
        margin-top: 100px;
        margin-bottom: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        background-color: rgb(105, 105, 105);
        padding: 30px 10px;
        width: 90%;
        max-width: 1740px;
        max-height: max-content;
        border-radius: 15px;
        position: relative;
    }
    #cards_featured_special {
        margin-top: 100px;
        margin-bottom: 100px;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        background-color: rgb(105, 105, 105);
        padding: 30px 10px;
        width: 90%;
        max-width: 1740px;
        max-height: max-content;
        border-radius: 15px;
        position: relative;
    }
    #OTSIKKO {
        font-family: 'Road Rage', Arial;
        position: absolute;
        font-size: 45px;
        top: -65px;
        left: 0px;
        color: yellow;
        background-color: rgb(105, 105, 105);
        width: max-content;
        padding: 0px 10px 10px;
        border-radius: 10px;
    }
    .timer {
        font-family: 'Monospace', Arial;
        position: absolute;
        font-size: 15px;
        top: -20px;
        right: 0px;
        color: yellow;
        background-color: rgb(105, 105, 105);
        width: 290px;
        padding: 5px 5px 10px;
        border-radius: 10px 10px 0px 0px;
        text-align: center;
        display: block;
        font-weight: 700;
    }
    .card {
        display: flex;
        background-color: rgb(148, 148, 150);
        width: 230px;
        height: 340px;
        border-radius: 15px;
        padding: 0px 10px;
        flex-direction: column;
        justify-content: space-between;
        align-items: center;
        color: white;
        font-family: 'Poppins', Arial;
        font-size: 22px;
        margin: 15px 10px;
        -webkit-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        -moz-box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.75);
        text-align: center;
        overflow: hidden;
    }
    .card span {
        display: flex;
        height: 30px;
        align-items: center;
    }
    #v_buck {
        margin-left: 5px;
    }
    #image {
        /*DEBUG BORDER
    border: 4px solid red; */
        max-height: 250px;
    }
    #introduce,
    #introduce1 {
        font-size: 10px;
        color: rgb(82, 82, 87);
    }
    footer {
        padding: 10px;
        font-family: 'Indie Flower', Helvetica, sans-serif;
        text-align: center;
        text-decoration: none;
        color: white;
    }
    footer a {
        text-decoration: none;
        color: white;
    }
}
<!DOCTYPE html>
<html>

<head>

    <title>Fortnite itemshop tracker!</title>
<style type="text/css">

</style>
    <link rel="stylesheet" href="style.css?v=1.0">
    <link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
    <link rel="manifest" href="img/site.webmanifest">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

</head>

<body>


    <header>
        <h1>Pinja's daily itemshop tracker</h1>
        <h3>[Work in progress]</h3>
    </header>
    <div id="cards_daily">

        <H1 id="OTSIKKO">Daily offers</H1>
        <div class="timer">
            Daily shop reset in: <span id="time"></span>
        </div>


    </div>
    <div id="cards_featured_special">
        <H1 id="OTSIKKO">Featured specials</H1>
        <div class="timer">
            Bundles are not included!
        </div>

    </div>
    <div id="cards_featured">
        <H1 id="OTSIKKO">Featured</H1>
        <div class="timer">
            Bundles are not included!
        </div>

    </div>
</body>

</html>

Choose Your Own Adventure (redo)

copy iconCopydownload iconDownload
if (game_2 == "TRAIN") {
var game_s = prompt("You have chosen SORA! The wielder of the Keyblade! You must fight the mighty KRATOS! The god of war! How will you prepare? (TRAIN/ADVENTURE)");
-----------------------
if (game_2 == "TRAIN") {
var game_s = prompt("You have chosen SORA! The wielder of the Keyblade! You must fight the mighty KRATOS! The god of war! How will you prepare? (TRAIN/ADVENTURE)");

Optaplanner multithreading exception: &quot;The externalObject ... has no known workingObject&quot;

copy iconCopydownload iconDownload
@PlanningSolution
class ReforgePlanningSolution @JvmOverloads constructor(
    @PlanningEntityCollectionProperty
    val availableItems: List<ItemPlanningEntity>? = null,
    @ProblemFactCollectionProperty
    val allReforges: List<ReforgeProblemFact>? = null,
    @PlanningScore
    val score: HardSoftScore? = null
)
val solverJob = solverManager.solve(UUID.randomUUID(), ReforgePlanningSolution(availableItems, allReforges))
-----------------------
@PlanningSolution
class ReforgePlanningSolution @JvmOverloads constructor(
    @PlanningEntityCollectionProperty
    val availableItems: List<ItemPlanningEntity>? = null,
    @ProblemFactCollectionProperty
    val allReforges: List<ReforgeProblemFact>? = null,
    @PlanningScore
    val score: HardSoftScore? = null
)
val solverJob = solverManager.solve(UUID.randomUUID(), ReforgePlanningSolution(availableItems, allReforges))
-----------------------
Caused by: java.lang.IllegalStateException: The externalObject (2018-10-01T10:15-12:15) with planningId ((class org.optaplanner.examples.conferencescheduling.domain.Timeslot, 0)) has no known workingObject (null).
Maybe the workingObject was never added because the planning solution doesn't have a @ProblemFactCollectionProperty annotation on a member with instances of the externalObject's class (class org.optaplanner.examples.conferencescheduling.domain.Timeslot).
    at org.optaplanner.core.impl.domain.lookup.PlanningIdLookUpStrategy.lookUpWorkingObject(PlanningIdLookUpStrategy.java:76)

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) from a local file

copy iconCopydownload iconDownload
import json

with open('monsters.json', encoding='utf-8-sig') as f:
    data = json.load(f)
json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)
-----------------------
import json

with open('monsters.json', encoding='utf-8-sig') as f:
    data = json.load(f)
json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)

Javascript: Sort data based on nested start_date and end_date

copy iconCopydownload iconDownload
const data = [ { id: "helsinki:af52xknl3q", name: { fi: "Ruutia! -tanssifestivaali 2021", en: "Ruutia! Dance Festival 2021", sv: "Ruutia! -dansfestivalen 2021", zh: null, }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "https://www.hurjaruuth.fi/ruutia-kansainvalinen-tanssifestivaali-lapsille-ja-nuorille/", modified_at: "2021-09-08T10:04:05.594Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "The annual festival Ruutia! for children and young presents new Finnish and international dance and action theatre performances. ", body: "<p>The annual festival Ruutia! for children and young presents new Finnish and international dance and action theatre performances.&nbsp;</p>\n<p></p>\n<p>Helsinki<br>25.8.-26.9.2021</p>", images: [ { url: "https://api.hel.fi/linkedevents/media/images/Dynamo---BARK-2-269.jpg", copyright_holder: "", license_type: { id: 1, name: "All rights reserved.", }, }, ], }, tags: [ { id: "linkedevents:yso:p1278", name: "dance (performing arts)", }, { id: "linkedevents:yso:p1304", name: "festivals", }, { id: "linkedevents:yso:p4804", name: "children's culture", }, ], event_dates: { starting_day: "2021-08-24T21:01:00.000Z", ending_day: "2021-09-26T20:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af52w5bga4", name: { fi: "DocPoint -dokumenttielokuvafestivaali 2022", en: "DocPoint -Helsinki Documentary Film Festival 2022", sv: "DocPoint -dokumentärfilmsfestivalen 2022", zh: "DocPoint - 赫尔辛基纪录片电影节2022", }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "https://docpointfestival.fi", modified_at: "2021-09-08T10:04:05.595Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "DocPoint - Helsinki Documentary Film Festival takes place in winter bringing the best new documentaries from Finland and abroad", body: "<p>DocPoint - Helsinki Documentary Film Festival takes place in winter bringing the best new documentaries from Finland and abroad, as well as documentary film classics from last decades.&nbsp;</p>\n<p></p>\n<p>Helsinki<br>31.1.-6.2.2022</p>", images: [ { url: "https://api.hel.fi/linkedevents/media/images/docpoint2021.jpg", copyright_holder: "", license_type: { id: 1, name: "All rights reserved.", }, }, ], }, tags: [ { id: "linkedevents:yso:p1235", name: "films", }, { id: "linkedevents:yso:p1304", name: "festivals", }, { id: "linkedevents:yso:p13105", name: "documentary films", }, ], event_dates: { starting_day: "2022-01-30T22:01:00.000Z", ending_day: "2022-02-06T21:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af52v47mu4", name: { fi: "Baltic Circle -teatterifestivaali 2021", en: "Baltic Circle Festival 2021", sv: "Baltic Circle -teaterfestival 2021", zh: null, }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "http://www.balticcircle.fi", modified_at: "2021-09-08T10:04:05.596Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "The international theatre festival Baltic Circle spreads across the city in November.", body: "<p>The international theatre festival Baltic Circle spreads across the city in November.</p>\n<p></p>\n<p>Helsinki<br>19.-27.11.2021</p>", images: [], }, tags: [ { id: "linkedevents:yso:p1304", name: "festivals", }, { id: "linkedevents:yso:p2315", name: "theatre events", }, { id: "linkedevents:yso:p2625", name: "theatre", }, ], event_dates: { starting_day: "2021-11-18T22:01:00.000Z", ending_day: "2021-11-27T21:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af52vvq2fa", name: { fi: "We Jazz 2021", en: "We Jazz 2021", sv: null, zh: null, }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "https://wejazz.fi/", modified_at: "2021-09-08T10:04:05.596Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "We Jazz Festival will be held in Helsinki for the eighth time in November-December.", body: "<p>We Jazz Festival will be held in Helsinki for the eighth time in November-December.&nbsp;</p>\n<p></p>\n<p>Presenting the cutting edge of domestic and international jazz, the festival spreads around Helsinki. The program includes e.g. Greg Foat 7tet (UK), Lucia Cadotsch Speak Low, Antti Lötjönen Quintet East, Ilmiliekki Quartet, Iro Haarla Presents: Leo Records, Koma Saxo feat. Sofia Jernberg, OK:KO and Timo Lassy Trio.</p>\n<p></p>\n<p>Helsinki</p>\n<p>28.11.-5.12.2021</p>\n<p>Tickets from Tiketti</p>\n<p></p>\n<p>The guidelines and instructions by authorities concerning covid-19 will be followed.&nbsp;</p>", images: [], }, tags: [ { id: "linkedevents:yso:p1304", name: "festivals", }, { id: "linkedevents:yso:p1808", name: "music", }, { id: "linkedevents:yso:p4484", name: "jazz", }, ], event_dates: { starting_day: "2021-11-27T22:01:00.000Z", ending_day: "2021-12-05T21:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af3neqvhnq", name: { fi: "Helsinki Design Week 2021", en: "Helsinki Design Week 2021", sv: "Helsinki Design Week 2021", zh: "2021赫尔辛基设计周", }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "http://www.helsinkidesignweek.com", modified_at: "2021-09-08T10:04:05.597Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "HDW is a series of smaller events selected through an open event search, and a calendar of events is published here. ", body: "<p></p>\n<p>HDW is a series of smaller events selected through an open event search, and a calendar of events is published here. There will be 80 design-themed events, from open showrooms and studios to smaller exhibitions, workshops for the whole family and walking tours. The programme includes Aalto University’s Designs for a Cooler Planet, where the theme is resource wisdom. The ensemble includes three different exhibition ensembles as well as webinars open to everyone. HDW visitors have the opportunity to learn about radical and multidisciplinary ideas, research, and prototypes in fashion, design and architecture that will contribute to a resource-wise future.&nbsp;</p>\n<p></p>\n<p>The festival programme includes an exhibition by the legendary sculptor and jewelry artist Björn Weckström, which celebrates the long career of the versatile artist. The exhibition, which opens at the Didrichsen Art Museum, features sculptures of acrylic, bronze, stone and glass. Also on display are oil paintings on sailcloths that combine fine art with sailing, Weckström’s second calling.&nbsp;</p>\n<p></p>\n<p>The Design Museum’s Design Super Week includes the exhibition as well as a lunch discussion by the Graphic Designer of the Year Marina Vezik, guided remote tours of the Iittala – Kaleidoscope: From Nature to Culture exhibition and much more.&nbsp;&nbsp;</p>\n<p></p>\n<p>Exceptional conditions due to the Covid19 pandemic continue, and this has been taken into account in planning the events for September.</p>\n<p></p>\n<p>Helsinki, Internet<br>9.-19.9.2021</p>", images: [ { url: "https://api.hel.fi/linkedevents/media/images/HDW_LastenDesignviikko9304_.jpg", copyright_holder: "", license_type: { id: 1, name: "All rights reserved.", }, }, ], }, tags: [ { id: "linkedevents:yso:p1304", name: "festivals", }, { id: "linkedevents:yso:p360", name: "cultural events", }, { id: "linkedevents:yso:p6455", name: "design (artistic creation)", }, ], event_dates: { starting_day: "2021-09-08T21:01:00.000Z", ending_day: "2021-09-19T20:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af44doctru", name: { fi: "Etnosoi!-festivaali 2021", en: "Etnosoi! Festival 2021", sv: null, zh: null, }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "https://www.etnosoi.fi/", modified_at: "2021-09-08T10:04:05.617Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "The annual Etnosoi! Festival celebrating different musical cultures from around the world will be organized in the Helsinki Metropolitan area next November.", body: "<p>The annual Etnosoi! Festival celebrating different musical cultures from around the world will be organized in the Helsinki Metropolitan area next November.</p>\n<p></p>\n<p>Helsinki, Espoo, Vantaa</p>\n<p>5.-14.11.2021</p>", images: [ { url: "https://api.hel.fi/linkedevents/media/images/ES_Lankalogo2.jpg", copyright_holder: "", license_type: { id: 1, name: "All rights reserved.", }, }, ], }, tags: [ { id: "linkedevents:yso:p1304", name: "festivals", }, { id: "linkedevents:yso:p1808", name: "music", }, { id: "linkedevents:yso:p3065", name: "world music", }, ], event_dates: { starting_day: "2021-11-04T22:01:00.000Z", ending_day: "2021-11-14T21:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af5binysse", name: { fi: "Taideperformanssi: `Mielellään Osoitus`", en: "Art performance: `Mind-H-App`y ProtestOhLook`", sv: null, zh: null, }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "https://www.terotakala.com/mo2021.html", modified_at: "2021-09-08T10:04:05.664Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "Art performance.", body: "<p>Art performance. Digital street art. Digital art<br>graphics combined with the moving around in the space of conceptual art dealing with the processing-the-thing using the concept of protest-culture<br>as material.</p>\n<p>Artist: Tero Takala</p>\n<p>Helsinki</p>\n<p>Varying locations in the city centre (eg. Kaivokatu, Mannerheimintie, Aleksanterinkatu, Keskuskatu etc.).</p>\n<p>Starting 18.6.2021 (not necessarily daily) mainly until approx. when rainy days of autumn begin . At varying times during the day.<br><br>Weatherpermitting.</p>\n<p>Free of charge</p>", images: [ { url: "https://api.hel.fi/linkedevents/media/images/Taideperformanssi_Mielell%C3%A4%C3%A4n_Osoitus_2_c_Tero_Takala_location_only.jpg", copyright_holder: "", license_type: { id: 1, name: "All rights reserved.", }, }, ], }, tags: [ { id: "linkedevents:yso:p4445", name: "street art", }, { id: "linkedevents:yso:p21073", name: "digital art", }, { id: "linkedevents:yso:p4098", name: "performance (art forms)", }, { id: "linkedevents:yso:p360", name: "cultural events", }, { id: "linkedevents:yso:p2739", name: "fine arts", }, ], event_dates: { starting_day: "2021-06-17T21:01:00.000Z", ending_day: "2021-09-30T20:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af44crcsam", name: { fi: "IHME Helsinki: To Burn, Forest, Fire", en: "IHME Helsinki: To Burn, Forest, Fire", sv: null, zh: null, }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "https://www.ihmehelsinki.fi/ihme-teos-2021/", modified_at: "2021-09-08T10:04:05.904Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "The Scottish artist Katie Paterson’s IHME Helsinki Commission 2021, To Burn, Forest, Fire, consists of the scents of the first forest on Earth 385 millions", body: "<p>The Scottish artist Katie Paterson’s IHME Helsinki Commission 2021, To Burn, Forest, Fire, consists of the scents of the first forest on Earth 385 millions years ago and of the last forest of the age of climate crisis. These scents will be turned into incense and burned in various parts of Helsinki in September 2021.</p>\n<p></p>\n<p>Katie Paterson (born 1981, Scotland) is widely regarded as one of the leading artists of her generation. Collaborating with scientists and researchers across the world, Paterson’s projects consider the place on Earth in the context of geological time and change. Katie Paterson Studio conducts long-term background work with researchers. The ideas for art works spring from the artist’s imagination, but the ability to transform those ideas into finished art works is underpinned by scientific research.</p>\n<p></p>\n<p>Helsinki, various venues, e.g. the Crypt of Helsinki Cathedral, King´s Island, the National Museum and Cultural Centre Stoa.</p>\n<p>1.-30.9.2021&nbsp;</p>\n<p></p>\n<p>The exact venues and times from IHME Helsinki's website.</p>\n<p>Free entry, duration approx. 1 h</p>\n<p></p>\n<p>Special invited guests for this project will be deaf, blind and deaf-blind people. IHME is arranging visits in collaboration with the Finnish Association of the Deaf, Helsinki and Uusimaa Visually Impaired Association and the Finnish Deafblind Association.</p>\n<p></p>\n<p>The art work is part of Helsinki Biennial Inspired series.</p>", images: [ { url: "https://api.hel.fi/linkedevents/media/images/Katie-Paterson-To-Burn-For.jpg", copyright_holder: "", license_type: { id: 1, name: "All rights reserved.", }, }, ], }, tags: [ { id: "linkedevents:yso:p2851", name: "art", }, { id: "linkedevents:yso:p5121", name: "exhibitions", }, { id: "linkedevents:yso:p6889", name: "art exhibitions", }, ], event_dates: { starting_day: "2021-08-31T21:01:00.000Z", ending_day: "2021-09-30T20:59:00.000Z", additional_description: null, }, }, { id: "helsinki:af5k3544qq", name: { fi: "Rakkautta & Anarkiaa 2021", en: "Love & Anarchy 2021", sv: "Kärlek & Anarki 2021", zh: null, }, source_type: { id: 1, name: "LinkedEvents", }, info_url: "https://hiff.fi/liput", modified_at: "2021-09-08T10:04:06.091Z", location: { lat: 60.170833587646484, lon: 24.9375, address: { street_address: null, postal_code: null, locality: null, }, }, description: { intro: "The 34th Helsinki International Film Festival – Love & Anarchy takes place next September.", body: "<p>The 34th Helsinki International Film Festival – Love &amp; Anarchy takes place next September.</p>\n<p></p>\n<p>The film festival proudly presents new films from well-known filmmakers and fresh talents alike. These are the films which you won't find elsewhere in Finland.</p>\n<p></p>\n<p>Festival programme is a candid mix of bold, controversial and visually stunning new films from all over the world.</p>\n<p></p>\n<p>Helsinki</p>\n<p>16.-26.9.2021</p>\n<p></p>\n<p>Tickets 10/85€ (serier ticket incl. 10 films)</p>\n<p></p>\n<p>Programme and the schedule will be published on Thursday 2 September, which is also the start date of the serial cards' sales. Single tickets sales start on Thursday 9 September.</p>", images: [ { url: "https://api.hel.fi/linkedevents/media/images/holmonuorisydan_250918_mari.jpg", copyright_holder: "", license_type: { id: 1, name: "All rights reserved.", }, }, ], }, tags: [ { id: "linkedevents:yso:p1235", name: "films", }, { id: "linkedevents:yso:p1304", name: "festivals", }, ], event_dates: { starting_day: "2021-09-15T21:01:00.000Z", ending_day: "2021-09-26T20:59:00.000Z", additional_description: null, }, }, ];

console.log("before")
data.forEach(date => console.log(date.event_dates.starting_day))

data.sort((a,b) => { 
  if(a.event_dates.starting_day > b.event_dates.starting_day) return 1;
  if(a.event_dates.starting_day < b.event_dates.starting_day) return -1;
  return 0;
})

console.log("after")
data.forEach(date => console.log(date.event_dates.starting_day))

console.log(data);

How to Pivot Columns of a Pandas DataFrame into Inner-most Level Index without Using df.iterrows()?

copy iconCopydownload iconDownload
>>> print(df.agg(str, axis='columns').str.cat(sep='\n\n'))
#                     1
Name          Bulbasaur
Type 1            Grass
Type 2           Poison
HP                   45
Attack               49
Defense              49
Sp. Atk              65
Sp. Def              65
Speed                45
Generation            1
Legendary         False
Name: 0, dtype: object

#                   2
Name          Ivysaur
Type 1          Grass
Type 2         Poison
HP                 60
Attack             62
Defense            63
Sp. Atk            80
Sp. Def            80
Speed              60
Generation          1
Legendary       False
Name: 1, dtype: object

#                    3
Name          Venusaur
Type 1           Grass
Type 2          Poison
HP                  80
Attack              82
Defense             83
Sp. Atk            100
Sp. Def            100
Speed               80
Generation           1
Legendary        False
Name: 2, dtype: object
>>> print(df.reset_index().agg(str, axis='columns').str.replace(r'^index\s*', '', regex=True).str.cat(sep='\n\n'))
0
#                     1
Name          Bulbasaur
Type 1            Grass
Type 2           Poison
HP                   45
Attack               49
Defense              49
Sp. Atk              65
Sp. Def              65
Speed                45
Generation            1
Legendary         False
-----------------------
>>> print(df.agg(str, axis='columns').str.cat(sep='\n\n'))
#                     1
Name          Bulbasaur
Type 1            Grass
Type 2           Poison
HP                   45
Attack               49
Defense              49
Sp. Atk              65
Sp. Def              65
Speed                45
Generation            1
Legendary         False
Name: 0, dtype: object

#                   2
Name          Ivysaur
Type 1          Grass
Type 2         Poison
HP                 60
Attack             62
Defense            63
Sp. Atk            80
Sp. Def            80
Speed              60
Generation          1
Legendary       False
Name: 1, dtype: object

#                    3
Name          Venusaur
Type 1           Grass
Type 2          Poison
HP                  80
Attack              82
Defense             83
Sp. Atk            100
Sp. Def            100
Speed               80
Generation           1
Legendary        False
Name: 2, dtype: object
>>> print(df.reset_index().agg(str, axis='columns').str.replace(r'^index\s*', '', regex=True).str.cat(sep='\n\n'))
0
#                     1
Name          Bulbasaur
Type 1            Grass
Type 2           Poison
HP                   45
Attack               49
Defense              49
Sp. Atk              65
Sp. Def              65
Speed                45
Generation            1
Legendary         False
-----------------------
df.stack().to_string('output.txt')
0  #                     1
   Name          Bulbasaur
   Type 1            Grass
   Type 2           Poison
   HP                   45
   Attack               49
   Defense              49
   Sp. Atk              65
   Sp. Def              65
   Speed                45
   Generation            1
   Legendary         False
1  #                     2
   Name            Ivysaur
   Type 1            Grass
   Type 2           Poison
   HP                   60
   Attack               62
   Defense              63
   Sp. Atk              80
   Sp. Def              80
   Speed                60
   Generation            1
   Legendary         False
2  #                     3
   Name           Venusaur
   Type 1            Grass
   Type 2           Poison
   HP                   80
   Attack               82
   Defense              83
   Sp. Atk             100
   Sp. Def             100
   Speed                80
   Generation            1
   Legendary         False
-----------------------
df.stack().to_string('output.txt')
0  #                     1
   Name          Bulbasaur
   Type 1            Grass
   Type 2           Poison
   HP                   45
   Attack               49
   Defense              49
   Sp. Atk              65
   Sp. Def              65
   Speed                45
   Generation            1
   Legendary         False
1  #                     2
   Name            Ivysaur
   Type 1            Grass
   Type 2           Poison
   HP                   60
   Attack               62
   Defense              63
   Sp. Atk              80
   Sp. Def              80
   Speed                60
   Generation            1
   Legendary         False
2  #                     3
   Name           Venusaur
   Type 1            Grass
   Type 2           Poison
   HP                   80
   Attack               82
   Defense              83
   Sp. Atk             100
   Sp. Def             100
   Speed                80
   Generation            1
   Legendary         False
-----------------------
import pandas as pd
import os

df = pd.read_csv('pokemon_data.csv')
with open('output.txt', 'w') as f:
    def write_pokemon(pokemon):
        f.write('\n\n')
        f.write(pokemon.to_string())

    df.apply(write_pokemon, axis=1)

Incorrect direction of element using anchor tag

copy iconCopydownload iconDownload
<section id="contact">... </section>
<div style="clear:both; display:block"></div>
<section id="contact"> Content Here.... </section>
<section id="contact">.....</section> 
<section class="col-xs-12" id="contact">.... </section>
-----------------------
<section id="contact">... </section>
<div style="clear:both; display:block"></div>
<section id="contact"> Content Here.... </section>
<section id="contact">.....</section> 
<section class="col-xs-12" id="contact">.... </section>
-----------------------
<section id="contact">... </section>
<div style="clear:both; display:block"></div>
<section id="contact"> Content Here.... </section>
<section id="contact">.....</section> 
<section class="col-xs-12" id="contact">.... </section>
-----------------------
<section id="contact">... </section>
<div style="clear:both; display:block"></div>
<section id="contact"> Content Here.... </section>
<section id="contact">.....</section> 
<section class="col-xs-12" id="contact">.... </section>
-----------------------
<section id="contact">... </section>
<div style="clear:both; display:block"></div>
<section id="contact"> Content Here.... </section>
<section id="contact">.....</section> 
<section class="col-xs-12" id="contact">.... </section>

Community Discussions

Trending Discussions on legendary
  • Deserializing JSON to a Dictionary&lt;string, Item&gt; with Item being abstract
  • Output all results of findstr to seperate txt files
  • Getting unexpected fault address error when unmarshalling json from bolt database in external function
  • cannot find -lbgi | codeblocks
  • Changing many same class DIV's color based on response value
  • Choose Your Own Adventure (redo)
  • Optaplanner multithreading exception: &quot;The externalObject ... has no known workingObject&quot;
  • json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) from a local file
  • Javascript: Sort data based on nested start_date and end_date
  • Identifying natural languages from small samples in Python
Trending Discussions on legendary

QUESTION

Deserializing JSON to a Dictionary&lt;string, Item&gt; with Item being abstract

Asked 2022-Feb-18 at 19:47

I'm looking to deserialize a JSON string to a Dictionary<string, Item> with Item being an abstract class. I serialize many types of items, some being Weapons, some being Armour, Consumables, etc.

Error: Newtonsoft.Json.JsonSerializationException: 'Could not create an instance of type Item. Type is an interface or abstract class and cannot be instantiated.

EDIT: I'm using Newtonsoft.Json for serializing / deserializing

Deserialization code:

public Dictionary<string, Item> LoadItemDictionary()
{
    Dictionary<string, Item> items = new Dictionary<string, Item>();

    using (var reader = new StreamReader(ITEM_DICTIONARY_PATH, new UTF8Encoding(false)))
    {
        string json = reader.ReadToEnd();

        items = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json);
    }

    return items;
}

JSON code:

{
  "excalibur": {
    "damage": 9999,
    "critChance": 10,
    "itemID": "excalibur",
    "iconLink": "",
    "name": "Excalibur",
    "description": "placeholder",
    "itemType": 1,
    "rarity": 4,
    "stackSize": 1,
    "canBeSold": false,
    "buyPrice": 0,
    "sellPrice": 0
  }
}

Item class:

public abstract class Item
{
    public string iconLink = string.Empty;

    public string name = string.Empty;
    public string description = string.Empty;
    public ItemType itemType = ItemType.NONE;
    public ItemRarity rarity = ItemRarity.COMMON;

    public int stackSize = 1;

    public bool canBeSold = false;

    public int buyPrice = 0;
    public int sellPrice = 0;

    public enum ItemRarity
    {
        COMMON,
        UNCOMMON,
        RARE,
        MYTHIC,
        LEGENDARY,
    }

    public enum ItemType
    {
        NONE,
        WEAPON,
        ARMOUR,
        CONSUMABLE,
    }
}

Weapon Example:

public class Weapon : Item
{
    public int damage = 0;
    public int critChance = 0;
    public new ItemType itemType = ItemType.WEAPON;
}

ANSWER

Answered 2022-Feb-18 at 19:47

You can use custom converter to be able to deserialize to different types in same hierarchy. Also I highly recommend using properties instead of fields. So small reproducer can look like this:

public abstract class Item
{
    public virtual ItemType Type => ItemType.NONE; // expression-bodied property

    public enum ItemType
    {
        NONE,
        WEAPON,
        ARMOUR,
        CONSUMABLE,
    }
}

public class Weapon : Item
{
    public override ItemType Type => ItemType.WEAPON; // expression-bodied property
    public string SomeWeaponProperty { get; set; }
}

Custom converter:

public class ItemConverter : JsonConverter<Item>
{
    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer, Item? value, JsonSerializer serializer) => throw new NotImplementedException();

    public override Item ReadJson(JsonReader reader, Type objectType, Item existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // TODO handle nulls
        var jObject = JObject.Load(reader);
        Item result;
        switch (jObject.GetValue("type", StringComparison.InvariantCultureIgnoreCase).ToObject<Item.ItemType>(serializer))
        {
            case Item.ItemType.WEAPON:
                result = jObject.ToObject<Weapon>();
                break;
            // handle other types
            // case Item.ItemType.ARMOUR: 
            // case Item.ItemType.CONSUMABLE:
            case Item.ItemType.NONE:
            default:
                throw new ArgumentOutOfRangeException();
        }

        return result;
    }
}

and example usage (or mark Item with JsonConverterAttribute):

var item = new Weapon();
var settings = new JsonSerializerSettings
{
    Converters = { new ItemConverter() }
};
string json = JsonConvert.SerializeObject(item, settings);
var res = JsonConvert.DeserializeObject<Item>(json, settings);

Console.WriteLine(res.GetType()); // prints Weapon

Source https://stackoverflow.com/questions/71178309

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install legendary

Tip: When using PowerShell with the standalone executable, you may need to replace legendary with .\legendary in the commands below. When using the prebuilt Windows executables of version 0.20.14 or higher this should open a new window with the Epic Login. Otherwise, authentication is a little finicky since we have to go through the Epic website and manually copy a code. The login page should open in your browser and after logging in you should be presented with a JSON response that contains a code ("sid"), just copy the code into the terminal and hit enter. Alternatively you can use the --import flag to import the authentication from the Epic Games Launcher (manually specifying the used WINE prefix may be required on Linux). Note that this will log you out of the Epic Launcher. This will fetch a list of games available on your account, the first time may take a while depending on how many games you have.

Support

For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

Explore Related Topics

Share this Page

share link
Reuse Pre-built Kits with legendary
Compare Game Engine Libraries with Highest Support
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.