Xbox Game Pass, Play Anywhere, I Think I Get It

The start of Q4 2020 was supposed to be an incredible time for PC gamers – or gamers in general. Firstly, Microsoft and Sony released their latest Next-Gen consoles, the Xbox Series X and S and the PlayStation 5. Secondly, AMD and NVIDIA battled it out in the GPU market, and AMD unleashed the Ryzen 5000 CPU family that ate Intel’s 10th generation for breakfast. And lunch. And supper, and dinner, and as a snack in between. Unfortunately for Intel, the only thing the 11th generation of Core Processors can do is hold AMD’s beer. In theory.

Excellent Hardware, No Stock, High Prices

I think by now, about six months later, we all know how things played out. It is not about having the best performance anymore. Instead, it is about who can get products on the shelves or into retailers’ warehouses so people can buy them. It seems like the price does not even matter. Some affluent enthusiast gamers may be more willing to overpay for their hobby, and first-time builders might not know any better. I am neither in the first nor in the last category. I could afford new PC hardware, but I am not willing to overpay a single Oren for any of it. The reasons for these prices are manifold, and many YouTubers discussed this very topic in many a video.

The story I want to tell you today is how all of that brought me into Microsoft’s console hardware and gaming service arms. Well, I guess I kind of already spoiled the reason: PC hardware is ridiculously overpriced, let alone readily available to buy. But there is more to it than that.

Read More »

Disable Banners on Sony Android TV (2019 Model)

I’ll try to make this quick. I started gaming on my 2019 Sony Android TV, and it frequently displayed a banner at the top with connection and resolution information. I hate when things constantly pop up, but it also blocked a pretty large portion of the screen. After some research, I found references about older versions of the operating system where Banners have their own menu item. Not on my TV, though, and I was starting to become very frustrated.

The option is there! It is in a location where I did not expect it. Open the settings and navigate to "Watching TV".

I associate that with a cable connection which is why I never looked there in the first place. I do not have cable. Next, disable "Info banner" and feel relieved.

My First Time Playing Battlefield, I Quit After 15 Minutes

I recently purchased the smaller of the Xbox Series, and it came in a bundle with three months of Game Pass Ultimate. As part of Game Pass Ultimate, you get access to EA Play games and, therefore, some of the Battlefield franchise. Since I have never played this game before, and I was in the mood for a simple shooter, I wanted to try it out. I am only interested in the single-player campaign and have no interest in the multiplayer modes. Hence, I base my thoughts on the single-player experience.

The idea of the introduction is not bad. You find yourself trapped in a car with the rest of your squad. It is apparent that there was an accident, and one of your buddies is badly injured or trapped and cannot get out. The situation is intense because the car is sinking in a lake or river or some other large body of water. Panic starts to break out, especially since your leader wants you to leave him behind. He hands you his handgun and orders you to shoot the windows so you and your fellow soldiers can get out. They, on the other hand, do not want to leave him behind. And from there, the game rewinds to where it all began.

Read More »

Ryse: Son of Rome Review

Germany-based company Crytek is best known for its Crysis and early Far Cry games and the CryEngine technology. Ryse: Son of Rome is probably not as well-known, and it certainly is not very popular. The game’s Metacritic score is 61, and the user score is 6.8. The biggest complaint I was able to ascertain was a lack of freedom and extreme repetitiveness. While I cannot argue with that, I also see it as a strength instead of a weakness. If you want to know why I encourage you to continue reading.

Read More »

Sign and Verify JWT With Hashicorp Vault REST API

Cryptography is complicated in more than just one way. Therefore, it is commonly recommended not to roll your own, but instead, employ tried and tested methods. Unless you are an experienced cryptographer, it is likely to overlook crucial things, for example, when to authenticate an encrypted message – before decrypting or after? This blog post is about JSON Web Tokens that are digitally signed with an RSA key. Instead of implementing the signing and verification code yourself, you should be using a dedicated server component to do the complex crypto for you, like Hashicorp Vault.

Read More »

Write ID3 mp3 Tags, Cover Art with Python and eyed3

In March 2019, I wrote about using Python with the "pytaglib" library to read and modify audio files’ metadata. This solution worked nicely for what I needed at the time, but as I rewrote my WAV-to-MP3 conversion in Python, I found that it lacked support for adding cover art to the files. After a bit of research, I found eyed3. It also comes with a nice side-effect: it does not require installation of the Taglib C++ library.

Installation is simple.

pip install eyeD3

Additionally, on Windows, you need this, too:

pip install python-magic-bin

For more details, visit the installation guide. Like my old pytaglib post, I will keep this one short and only show code samples for the most relevant tasks.

Before you do anything, import the eyed3 library, of course.

import eyed3

Load a file.

song = eyed3.load(file)

If the file does not yet have any tags, you must create them before setting any metadata.

if not song.tag:

Note that this erases existing tags, so only call that if you start from scratch. Now you are ready to set the individual tags or read them if you need them.

song.tag.artist = "Behemoth"
song.tag.album = "The Satanist"
song.tag.genre = "Black Metal"
song.tag.recording_date = 2014
song.tag.track_num = 4
song.tag.title = "Ora pro nobis Lucifer"

The important piece for me, write cover art.

with open(cover_art_filename, "rb") as cover_art:
    song.tag.images.set(3,, "image/jpeg")

The value 3 indicates that the front cover shall be set. See the documentation for other values. If you are an iTunes user, then select 0 for "Other". iTunes does not seem to like "Front Cover" 🙄.

You may run into a warning message like the following if you use genre names not defined in the ID3 specification.

eyed3.id3:WARNING: Non standard genre name

You do not need to worry about that. If it annoys you, add the following line to your code. eyed3 still writes the tag without any issue.


Convert Java POJO With Protobuf field to JSON Using Jackson

In this blog post, I will explain how to convert a regular Java class that contains a Protobuf message field to JSON using the Jackson library, for example, in a Spring Boot application as a return value of an @Controller method.

You might wonder, how this is such a big deal? After all, you can create complex POJO hierarchies, and Jackson will pick them up just fine. Well, maybe this error message will convince you.

o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [
    Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: 
    Type definition error: [simple type, class]; 
    nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle 
    (through reference chain: com.thecodeslinger.ppjs.web.dto.AwesomeDto["awesomePowerUp"]
        ->["defaultInstanceForType"])] with root cause

Java classes that you create with the Protobuf compiler require their JSON converter JsonFormat.Printer. So, how can we get Jackson and JsonFormat.Printer love each other and have a wedding together?

Simple: we create a custom JsonSerializer.

public class ProtobufSerializer extends JsonSerializer<Message> {

    private final JsonFormat.Printer protobufJsonPrinter = JsonFormat.printer();

    public void serialize(Message anyProtobufMessage, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        // The magic sauce: use the Protobuf JSON converter to write a raw JSON
        // string of the Protobuf message instance.

This class is very simple and can work with any Protobuf Message class instance. This way, it is universal and only needs to be written once. The main ingredient is the jsonGenerator.writeRawValue method that takes the input without modification. Since we already ensure a proper JSON format using Protobuf’s converter, this is no problem in this case. Otherwise, be careful with this method.

The last step is to annotate the Message field in the POJO, so Jackson knows what to do.

@JsonSerialize(using = ProtobufSerializer.class)
private final AwesomePowerUpOuterClass.AwesomePowerUp awesomePowerUp;

You can find a complete working example that uses Spring Boot and a REST endpoint on my Github account.

Install Minikube in VirtualBox on Remote Machine for Kubectl

At work, we are using Kubernetes as a way to run our application services. To test and debug deployments before they go into code review and to the development environment, a local Kubernetes is beneficial. That is where Minikube comes into play. Unfortunately for me, our application services require more resources than my work laptop can provide, especially RAM. Either I close all applications and run Minikube, or I have a helpful browser and IDE window open 😉.

Since I need the local K8s cluster from time to time, I wondered if I could run it on my personal computer and access it from my laptop. This way, I can dedicate at least six physical cores and 24 GB of RAM to the VM (even more, but that was a nice number and more than enough).

Read More »

OpenRGB – An RGB Software I Want to Use (It Runs on Linux!)

If you are in the market for anything gaming PC or gaming laptop related, chances are, you have come across the industry-wide trend of RGB illuminated hardware and peripherals. Everything is RGB, from the graphics card to the RAM, to your headset (because you can see the lights when you wear it 🙄), and many, many more. I am not against RGB lighting per se, but if you follow the industry as a PC hardware enthusiast, it is evident that in some aspects, this has gone too far.

Quick side note: after a rant about RGB software, I will show examples of using OpenRGB on Windows and Linux. If you are interested in only that, skip the rant and scroll to the bottom.

Read More »

Apple, Stop Parenting Me – Rant About iOS 14 Auto-Volume Reduction

Apple is a company that tends to believe it knows best what its customers want. Sometimes a company – not specific to Apple – does actually know better than the customer. Apple has been very active in the past years to push customer health and provide hardware, the Apple Watch, and software, the Health app, to facilitate this push in the form of products they can sell. I do not own an Apple Watch, but I genuinely view it as a good thing.

Now, with iOS 14, Apple has gone a bit too far with regards to health monitoring. It now enforces rules I, the customer and user of a device, cannot override. I am talking about the automatic volume reduction when iOS thinks I have been listening to loud audio for too long.

This is not okay!
This is not a situation where a company knows better.

It is actively limiting its product’s usefulness to me, the customer who paid a lot of money for it. I understand the motivation, but I cannot condone the action taken. Apple cannot even know why I turn up the volume to levels it deems inappropriate for a more extended period.

Here are a few examples, some of which already happened to me.

  1. Bluetooth-pairing the phone with my car’s audio system.

    I usually crank the phone’s volume to max to roughly match the other audio sources, like music on a USB stick (yes, I am a cave-man that has music on a stick).

  2. Listening to podcasts while going for a walk or run next to a busy road.

    Imagine my surprise when the voices speaking to me seemed to have disappeared because iOS lowered the volume to a point where the audio was drowned by traffic noise. I thought my phone had died – which has happened often enough thanks to an iOS bug that incorrectly reported battery percentage and dropped from 30% to turning off within 15-20 minutes.

  3. Listening with studio headphones that have a high input resistance (in ohm).

    I recently bought a new pair of headphones, and the quickest way to compare them with my old ones was to plug them into my phone. 80 Ω is not a lot, but enough to have to crank up the volume a bit higher to get a decent fun level. In the end, it is still much quieter compared to my PC soundcard that supports up to 600 Ω headphones.

No. 1 has not yet happened, but I assume it might once the world is rid of the COVID-19 pandemic, and I can/must travel to work a couple of times per month. On longer car rides, I usually listen to podcasts, and as mentioned, I turn up the volume on my phone in those cases. The other two issues have already managed to annoy me, and No. 3 prompted me to write this little rant – although that is the least likely of the three examples to occur regularly. Most of the time, it will be No. 2 when I am out walking or going for a run. The traffic noise is much worse than people talking to me. I am not even listening to music, which is also worse than people talking to me. I prefer Apple to turn down the car noise on the roads instead of my headphones. Until they can do that, stop messing with my volume, please.

(Is this a ploy to get me to buy horribly expensive AirPods Pro with
noise cancellation?)

I can agree that a notification is a good start to educate users. But please do not take any automatic action. At least make it configurable. I am an adult, and I should be able to decide for myself. On top of that, there are legitimate use-cases where a higher "theoretical" volume is required.

CMake C++ Custom Library on Windows “Undefined Reference” – No Error on Linux

Here is the short version with a quick setup of the situation and the fix. After that, I’ll elaborate a bit.



I have a custom C++ library and a separate project for tests (all based on Qt 6). The test project requires the library for execution.

Here is a short excerpt of the CMake scripts, first the library, then the tests.

project(wt2-shared VERSION 2.0.0 DESCRIPTION "WorkTracker2 Shared 

# To export symbols.

# Snip header + source definitions

add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS})

target_include_directories(${PROJECT_NAME} PUBLIC include/)
target_link_libraries(wt2-shared Qt6::Core Qt6::Sql)
project(wt2-shared-test VERSION 2.0.0 DESCRIPTION "WorkTracker2 
Shared Library Tests")

# Snip header + source definitions

add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})

target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDES})
target_link_libraries(${PROJECT_NAME} Qt6::Core Qt6::Test wt2-shared)


This error only occurred on Windows, and it does not matter which toolchain I used, be it MinGW or MSVC. The result was always the same.

The following shows the MinGW error.

[100%] Linking CXX executable wt2-shared-test.exe    
    undefined reference to `__imp__ZN4Data3Sql13SqlDataSourceC1E7QString'
    undefined reference to `__imp__ZN4Data3Sql13SqlDataSource4loadEv'
    undefined reference to `__imp__ZN4Data3Sql13SqlDataSourceC1E7QString'	
    undefined reference to `__imp__ZN4Data3Sql13SqlDataSource4loadEv'
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** 
wt2-shared-test/wt2-shared-test.exe] Error 1


The add_library definition in the CMakeLists.txt was incomplete.
To make it work, I added SHARED because I want a shared library.


Continue reading, though, to get the full picture. There is more to it than just making the library a shared one.

Read More »

CMake CLI Parameter “generator-name” Usage

This topic shouldn’t even require a blog post, but I find the CMake CLI usage rather odd when it comes to specifying a generator. Here’s a shortened "-h" output.

> cmake -h

cmake [options] <path-to-source>
cmake [options] <path-to-existing-build>
cmake [options] -S <path-to-source> -B <path-to-build>

Specify a source directory to (re-)generate a build system for it in the
current working directory.  Specify an existing build directory to
re-generate its build system.

-S <path-to-source>          = Explicitly specify a source directory.
-B <path-to-build>           = Explicitly specify a build directory.
-C <initial-cache>           = Pre-load a script to populate the cache.
-D <var>[:<type>]=<value>    = Create or update a cmake cache entry.
-U <globbing_expr>           = Remove matching entries from CMake cache.
-G <generator-name>          = Specify a build system generator.
-T <toolset-name>            = Specify toolset name if supported by
-A <platform-name>           = Specify platform name if supported by



The following generators are available on this platform (* marks default):
Visual Studio 16 2019        = Generates Visual Studio 2019 project files.
                                Use -A option to specify architecture.
Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files.
                                Optional [arch] can be "Win64" or "ARM".


Borland Makefiles            = Generates Borland makefiles.
* NMake Makefiles              = Generates NMake makefiles.
NMake Makefiles JOM          = Generates JOM makefiles.
MSYS Makefiles               = Generates MSYS makefiles.
MinGW Makefiles              = Generates a make file for use with
Unix Makefiles               = Generates standard UNIX makefiles.

Kate - Ninja                 = Generates Kate project files.
Kate - Unix Makefiles        = Generates Kate project files.
Eclipse CDT4 - NMake Makefiles
                            = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - MinGW Makefiles
                            = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Ninja         = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files.

These generator options do not look like valid parameter values to the "-G" option. But they are. So, if you want to compile on Windows using MinGW, you have to use this.

> cmake -S ../src -B ./ -G "MinGW Makefiles"

Or, if you prefer Visual Studio project files:

> cmake -S ../ -B ./ -G "Visual Studio 15 2017 Win64"

This "syntax" looks weird, and it tripped me for about 10 minutes until I found a sample and understood how it works.

Road to the Perfect Mini ITX PC (Part 5): Other Small Form-Factor ITX Cases

Previously on “Road to the Perfect Mini ITX PC”:

  1. Fractal Design Core 500
  2. NZXT H200
  3. Fractal Design Meshify C
  4. Lian Li TU150

The first two cases I had bought were before I became aware of all the mass-market and niche options that existed at that time. Not only have I learned about the DAN Case, NCase M1, and Streacom DA2, but companies have released more cases during the past year. I’m talking about the NZXT H1, the Cooler Master NR200, or, recently, Phanteks’ second attempt at the Evolv Shift. Even Lian Li’s TU150 landed during that time, my current case. There are even so many more cases, like the Louqe Ghost S1, the FormD T1, Sliger SM560, and many more.

Read More »

Road to the Perfect Mini ITX PC (Part 4): Lian Li TU150

In a few aspects, the Lian Li TU150 is comparable to the NZXT H200. One: for an ITX enclosure, it is on the bigger side. And two: it has a similarly closed-off front. Other than that, they are pretty different, though. In some areas, that is a good thing, and it is a bad thing in others.

In the timeframe of just over a year, this is the fourth (!) computer case that I have tried. Usually, it is the CPU or GPU that gets replaced more often 😅 It is also my current case, which means I can provide good pictures to visualize my thought process better.

Read More »