X39.io
A fancy world of magic, unicorns and a raging lazy dev

GDPR
by X39


As i currently lack the time to edit the website, here is what i do with your data:

==First things first==

This Webpage is currently using google analytics. This will change as soon as i got the time to remove it again. but that means that you are currently monitored whenever you navigate any of the pages here.

Apart from the above exception (which you can block using simple anti-tracking scripts till i removed it) no connection to the "outside internet" are done. Your data also is never shared with anybody in the outside world.

==Website==

  • The nginx server is running default logging for debuging purpose.
  • Google Analytics is running in this webpage for simple statistics service. Meaning your basic data is shared with google.
  • The PHP script this webpage is running sets a Cookie that allows to keep session informations. A session usually will be deleted after 30 minutes. Session data is not of importance for you (nothing will be set in there) but important for me to actually ... well ... do anything on this webpage.

==Applications==

  • Some applications are using update mechanisms which automatically runs at the startup. It communicates with this server. Default logging of nginx applies here too.
  • Applications updating are logged into an internal SQL table. The logged stats are: IP, Timestamp, API path. Those are logged for simple usage stats.

Inkscape - Good Software, Horrible Userexperience
by X39


I installed Inkscape like ages ago to do small edits on some SVG i had. It worked pretty damn good besides ... some problems...

The whole software is not designed so that some newcommer could pick it up easy. Ugly nested menus, way to specific snap options (which is theoretically good, but only for those who use inkscape on a regular basis! For EVERY other person, this is making things confusing AF, especially because not even all options can be put on at a single place) and generally a feel of lacking features due to them being so well hidden in nested menus or wrong terms that somebody not familiar will simply not find it.

Want an example of how hard this can be?

Microsoft provides the icon pack of visual studio for "free" but it has some lacking icons (eg. Tag has no NewTag variant)

Now, to edit this, you can use inkscape and join those two together so that they form a new 16x16 image

sounds easy right?

well ... it is not that simple afterall, but lets walk through this step as somebody new.

  1. You will pull both items into the current page
  2. You try to position them correctly whilst noticing that nothing snaps
  3. You search the snapping options (not knowing where they are, you ignore the righthand side as in most software, such options are at top whilst tools are left and righthand is current selected properties etc.) but cannot find them
  4. You google, to see a tutorial to do that and think "great"
  5. You try to position them correctly and everything still is not snapping
  6. You google again just to find out that those snapping options in the document properties are not all snapping options and enable snapping in the right bar for nodes too
  7. You position them correctly and export it
  8. You notice that the whole exported path is not usable because for some reason it is not in the right size and positoon
  9. You google how to change the page size
  10. You fiddle around a few mins until you got it to 16x16 px
  11. You export again, still not as it is displayed in inkscape
  12. You check the object just to see that its bounds are outside of the page area (and those got exported too)
  13. You try to find a way to crop the object to the visible page
  14. Few minutes later you realize that there is no inbuilt way to crop to the page (but the other way around which are the first few google results that will popup)
  15. Try to use the rectangle tool to create a rectangle at page size
  16. Try again because nothing appeared when you first tried
  17. Repeat step (16) up to the point where you try to just select everything
  18. Realize that you now have a ton of objects in your page
  19. Try to find some sort of object explorer, find none and google
  20. Google solution is not working, search icons on the right to find the treeview explorer
  21. Removing stuff from the explorer is not possible
  22. Write a rant
  23. Open everything in GIMP to do the same
  24. Be done in 20 minutes instead of 2 weeks of learning inkscape fully

In the end, Inkscape just feels bad!

There is a science field in the IT that is called Human-Computer-Interaction and everytime i think about giving inkscape a try, i notice that the whole software is not build in any way to suit to the average human.

It just feels like some developer put some option somewhere without any actual concept of grouping or awareness of other software available on the market.

I am fairly sure that experienced users can make good use of Inkscape, but as somebody who is not mainly doing such things but rather utilizing (or some may call it abusing) the tool to crop, manipulate etc. existing SVG/XAML paths the whole software feels bloated and not thought through.

[BotW] Seriously Nintendo fanboys ... the fuck is it with you?
by X39


Somebody not liking your game as much as you do through your fanboy glasses does not means they hate it...

they just do not use your fanboy-glasses and see the problems which also exist.

Example?

BotW is a good and solid game. It makes fun, got a beautiful world etc. etc.

However!!! It has design flaws which are unavoidable and probably annoyed most of the people playing the game.

Want examples?

The weapon durability system is horseshit... if weapons would "just" break and you could repair them if you bring them to a smith, probably ppl would be more ok with it. At last, it is a neat addition but executed horrible in a way that annoys and is not an addition to the gameplay.

Cooking is fun, but not in BotW. Yes it is neat for the first few times you do it but then you notice a big bummer: You lack a ton of quality of life (from now just refered to as QOL) features. Starting at the simplest: you cannot easily repeat your last cooking or make a bunch with the same. Just crafting eg. a potion feels cumbersome due to you being in need of having the right stuff in your inventory (which is fine) but you cannot see if you even got the right category of items. Due to the interface design, it simply does not feels right when you continue playing and need to cook to get health items, potions etc. it feels like you waste your time as this could be more simple. A simple book for example that opens up and allows to recraft anything you like. Picking ingredients would still be simple, but should be limited to what actually can be used in the current recipe

Motion Control shrines are just awful! It does not feels right to be in need of precise movement when you always can 100% freely move and rotate your object. They feel completly unnatural and anybody thinking they are "nice addition" is right, just that the execution is so wrong. Examples? There are shrines where you have to move a hammer with motion controls. So far so good right? But the hammer just has to swing from the left to the right, hitting a large ball. This however is deadly hard simply because the moment you start moving your joycon, the game moves the hammer. When you then rotate the hammer, the ball will fall off the ledge simply because your hammer is rotated slightly. This feels awful and youre happy when youre done with it. No challenge just pure anger about a broken mechanic.

The defensive mechanics like Shield Parry or jump-avoid are also completly horrible. The timing spot is way to short to get it off reliably, the enemies do not announce their attacks good enough to visually feel it, ... There is simply so much wrong with this mechanic... not to mention that the moment there is more then one enemy, you are simply fucked because all of theese things will not work anymore. So even if you by magic sit through hours to learn to parry correctly, it is no usable skill simply because the enemy behind you will just straigth hit you without a chance to parry or actually see that he is there.

could continue days with this! And it is awful that you fanboys do not want to notice this.

Do theese things hinder me from playing the game? Fuck no. But they exist! Everybody touching the game will experience them, everybody will get annoyed by them (you too) and everybody normal will not enjoy theese things as much as they could.

Theese are the reasons, why BotW should not be even considered as a Game of the Year ...

but they also do not make the game a bad one ... it is just not a perfect game.

In case somebody is in need of Full-Width TreeViewItem background highlighting
by X39


The Style:


                    <Style x:Key="FullRowTVI" TargetType="{x:Type TreeViewItem}">
                        <Setter Property="Background" Value="Transparent"/>
                        <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                        <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                        <Setter Property="Padding" Value="1,0,0,0"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type TreeViewItem}">
                                    <ControlTemplate.Resources>
                                        <ss:StaggeredThicknessConverter Left="True" Length="19" x:Key="TVIStaggeredThicknessConverter" EndType="{x:Type TreeView}"/>
                                    </ControlTemplate.Resources>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition MinWidth="19" Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition/>
                                        </Grid.RowDefinitions>
                                        <Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="0" Padding="0" Grid.ColumnSpan="3">
                                            <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
                                        </Border>
                                        <ToggleButton x:Name="Expander" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" Margin="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Converter={StaticResource TVIStaggeredThicknessConverter}}">
                                            <ToggleButton.Style>
                                                <Style TargetType="ToggleButton">
                                                    <Setter Property="Focusable" Value="False"/>
                                                    <Setter Property="Template">
                                                        <Setter.Value>
                                                            <ControlTemplate TargetType="ToggleButton">
                                                                <Grid Width="15" Height="13" Background="Transparent">
                                                                    <Path x:Name="ExpandPath" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1" Fill="#444" Data="M 4 0 L 8 4 L 4 8 Z"/>
                                                                </Grid>
                                                                <ControlTemplate.Triggers>
                                                                    <Trigger Property="IsChecked" Value="True">
                                                                        <Setter Property="Data" TargetName="ExpandPath" Value="M 0 4 L 8 4 L 4 8 Z"/>
                                                                    </Trigger>
                                                                </ControlTemplate.Triggers>
                                                            </ControlTemplate>
                                                        </Setter.Value>
                                                    </Setter>
                                                </Style>
                                            </ToggleButton.Style>
                                        </ToggleButton>
                                        <Border Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                            <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                                        </Border>
                                        <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"/>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsExpanded" Value="false">
                                            <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
                                        </Trigger>
                                        <Trigger Property="HasItems" Value="false">
                                            <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
                                        </Trigger>
                                        <MultiTrigger>
                                            <MultiTrigger.Conditions>
                                                <Condition Property="HasHeader" Value="false"/>
                                                <Condition Property="Width" Value="Auto"/>
                                            </MultiTrigger.Conditions>
                                            <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/>
                                        </MultiTrigger>
                                        <MultiTrigger>
                                            <MultiTrigger.Conditions>
                                                <Condition Property="HasHeader" Value="false"/>
                                                <Condition Property="Height" Value="Auto"/>
                                            </MultiTrigger.Conditions>
                                            <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/>
                                        </MultiTrigger>
                                        <Trigger Property="IsSelected" Value="true">
                                            <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                                        </Trigger>
                                        <MultiTrigger>
                                            <MultiTrigger.Conditions>
                                                <Condition Property="IsSelected" Value="true"/>
                                                <Condition Property="IsSelectionActive" Value="false"/>
                                            </MultiTrigger.Conditions>
                                            <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                                        </MultiTrigger>
                                        <Trigger Property="IsEnabled" Value="false">
                                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                    <Style TargetType="{x:Type TreeView}">
                        <Setter Property="ItemContainerStyle" Value="{StaticResource FullRowTVI}"/>
                    </Style>```

The Converter:

using System; using System.Globalization; using System.Windows; using System.Windows.Data; using System.Windows.Media;

/// <summary>
/// Adds up the left margin of the upper visual tree up to the point where the <see cref="Type"/> is no longer matching starting at 0.
/// Expects the <see cref="DependencyObject"/> as value, will simply return value if passed value is not of <see cref="Type"/> <see cref="DependencyObject"/>
/// <see cref="UnsetOnNullConverter.ConvertBack(Object, Type, Object, CultureInfo)"/> will always return <see cref="System.Windows.DependencyProperty.UnsetValue"/>.
/// </summary>
public class StaggeredThicknessConverter : IValueConverter
{
    /// <summary>
    /// The length that should be added each time.
    /// </summary>
    public double Length { get; set; }

    /// <summary>
    /// Type that will be searched for. Continues to count until null or this.
    /// If not set, will count until different parent is encountered.
    /// </summary>
    public Type EndType { get; set; }

    /// <summary>
    /// Sets wether the top part of <see cref="Thickness"/> should be affected.
    /// </summary>
    public bool Top { get; set; }
    /// <summary>
    /// Sets wether the bottom part of <see cref="Thickness"/> should be affected.
    /// </summary>
    public bool Bot { get; set; }
    /// <summary>
    /// Sets wether the left part of <see cref="Thickness"/> should be affected.
    /// </summary>
    public bool Left { get; set; }
    /// <summary>
    /// Sets wether the right part of <see cref="Thickness"/> should be affected.
    /// </summary>
    public bool Right { get; set; }

    /// <summary>
    /// Converts a value
    /// </summary>
    /// <param name="value">The value produced by the binding source.</param>
    /// <param name="targetType">The type of the binding target property.</param>
    /// <param name="parameter">The converter parameter to use.</param>
    /// <param name="culture">The culture to use in the converter.</param>
    /// <returns>A converted value. If the method returns null, the valid null value is used.</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is DependencyObject obj))
        {
            return value;
        }
        var actingtype = obj.GetType();
        Type objtype;
        double leftmargin = 0;

        while((objtype = (obj = VisualTreeHelper.GetParent(obj)).GetType()).IsEquivalentTo(actingtype) || (this.EndType != null && !objtype.IsEquivalentTo(this.EndType)))
        {
            if (objtype.IsEquivalentTo(actingtype))
            {
                leftmargin += this.Length;
            }
        }
        return new Thickness(
            this.Left ? leftmargin : 0,
            this.Top ? leftmargin : 0,
            this.Right ? leftmargin : 0,
            this.Bot ? leftmargin : 0);
    }

    /// <summary>
    /// Converts a value.
    /// </summary>
    /// <param name="value">The value that is produced by the binding target.</param>
    /// <param name="targetType">The type to convert to.</param>
    /// <param name="parameter">The converter parameter to use.</param>
    /// <param name="culture">The culture to use in the converter.</param>
    /// <returns>A converted value. If the method returns null, the valid null value is used.</returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return DependencyProperty.UnsetValue;
    }
}

python bullshittery - today: raw strings
by X39


dir = r"C:\somepath\log\"

results in SyntaxError: EOL while scanning string literal

lovely

Just killed my debian setup by accident ...
by X39


just took 8 hours to restore everything to a state where it was before (ok ... also fixed problems like reverse-dns lookup being wrong etc. :3)

anyways ... everything up running again

So ... you want to install a custom OS on your android phone ...
by X39


First of all: Congratulations! You chose a path full of pain, violence and incompetent idiots who do competent stuff ...

Want an example? Well ... if you are not by any chance using a mainstream-mainstream device (eg. Galaxy S4) you are fucked. Plan to buy at least one 64GB SD-Card as you most likely wont find any version of TWRP (the most common tool used for backup etc.) compatible with your phone AND up to date so that you can directly transfer to your PC.

Alternativly buy a USB-OTG cable, again it takes time for it to arrive on amazon or for you to find in your local electronics market ...

But what to do if you want to flash right now?

Well ... Skip Backup ... because for some reason those mind-dead developers thought it would be a great idea to write a comprehensive guide on how to build it on your own ... just ... that you cannot understand anything of it unless you ever build anything on your own.

Chances are you already did build something using make and eg. gcc, congratulations, the guide still is complete utter shit for you unless you did so for android :)

So you seek out again for the internet for more help...

New guide, new luck. This time, it tells you it is a step by step guide for people who have little to no experience in buidling android but want to LEARN how to do it ...

that LEARN already is a great indicator what is following ... a comprehensive guide how to do exactly nothing on a linux system ...

majority of those ppl facing problems here will be neither using LINUX nor they have ANY experience or ANY interest in learning how to build shit! FOR FUCK SAKE YOU MORONS ... you do stuff normal people want to use. You write guides for developers that are trying to get into that field. You do literally EVERYTHING to prevent ppl from using your shit clean thus they get frustrated and for fuck sake i exactly know that you hate those people for asking after they did not understood your "very comprehensive non-step-by-step guide to LEARN"

so ... here is what you have to do to actually avoid questions like that ...

  1. Write an actual step by step guide For some reason ... the knowledge about what a step by step guide is and why it is needed got lost somewhere in the eternal void of the internet ... so here is quickly a reminder: Step by Step guide can be done by setting up a new system (eg. in a VM, my comprehensive guide is: use apt to install it faggots) and then writing down EVERY interaction one does! Every mouse click, every input hell even if you move windows it can get important for the user (before you actually do this: DO NOT ... ppl tend to know how to handle windows). Also ... do not expect people to have your system, expect the major system to be used! The majority of people uses MS WINDOWS not any unix variant so fucking write your step by step guide from that perspective ... you only can build using linux? Then fucking write that down! Tell people they shall check out a step by step guide about how to install linux in a VM ...
  2. Fire whoever was responsible for the old guide Seriously ... whoever is too stupid to do the most simple thing in the world but rather writes down garbage for people who would ask for such things in IRC channels or EMAIL lists ... is not supposed to do any public relations shit.
  3. Clean up your pages simple example? Needed TWRP and lineageos for my SM-T560... there are multiple variants of this tablet out there, lineageos has no way to check for the modelnum whilst TWRP lists a magic SM-T560NU ... the dump idiot now thinks "ohhh thats mine!" but he is wrong like usual as the NU variant is qualcomm based ... incompatible stuff ya know ... so add more manifacturer info ... for fuck sake PLEASE how hard is it?! your whole page contains useless info but adding those things you need at build time anyways you cannot add?

If you follow theese 3 tiny steps, you are one step closer to actually being useful ...

Now here is my comprehensive guide to fix that whole shit for any tablet:

  1. Ignore those fuckheads and backup manually, either by your tablets manufacturer tool (giving you some crypting garbage backup you cannot use) or by downloading every file via eg. adb or another tool of your choice (google file transfer android and it should show up plenty)
  2. Make sure you actually backed up everything, no going back from here
  3. Try to find the right lineageos release for your phone ... use google to get the matching name for your modelnumber (do not just check the box as that is most likely not the full describor and there are differences in the models)
  4. Follow the actually really good guide of lineageos for your device (in case you need to get out of the download mode: PRESS ALL KEYS FOR ~5 SECONDS)
  5. Avoid using heimdall as it is a garbage tool (use odin)
  6. Burn your smartphone/tablet because nothing works
  7. Sleep a night
  8. Realize you slept over due to phone being still in recovery mode
  9. Repeat step 1-6 until it works
  10. Congratulations: you forgot to add google apps

I like trains - Today: Useful error messages
by X39


'malloc': 'void *(std::size_t)' differs in levels of indirection from 'void *(std::size_t)'

About the OnePlus5 and their first come last serve policy
by X39


I usually keep calm when things do not go as expected ... but this time? This time it is too much!

I ordered the OnePlus 5 as my new smartphone on tuesday and ... the entire delivery is a disaster ...

First you discover that ppl who ordered a half day after you, who patiently watched the livestream for that bloody damn fucking "access code" so that you could order the doomed phone, not only have their phone already sent, no! They also already received it.

Then after contacting the support, and ranting in reddit about that they fucked up their order sorting, your phone finally gets shipped. But wait! There is more!

Now that it finally got on the way to you, you feel kinda happy it arrived in the DHL HUB and you think "now nothing can go wrong, everything will be fine from here" but well ... not here, not now

"Technical issues" prevent further processing ... something that seems to be common with the OnePlus releases

so you start getting angry and contact DHL just to discover that finding the right contact formular is a mess ... after an hour of searching the right one you finally sent the message to them

hours later, still no reply ... you contact the one plus support and ask them .. they just say "our logistic specialist is on it" and thats it ... case closed, nothing to do ...

you start considering calling the support hotline but as angry as you are right now, you know you would just start yelling after 2 minutes when they repeat those default questions again and again and again and again just because they want to get you done ...

so here i am now ... fucking angry and writing a rant to calm down ... i am pissed, and already considered to cancel my OnePlus 5 and just grab ... idk ... a nokia ... one of the ancient ones

at last, this is the worst experience i EVER had with with delivery especially when it gets as expensive as it is right now (>500€ for that fucking phone) things like this are not acceptable ...

anyway ... i need to get back to F5ing my email inbox

A quick update about my modding & tool activities
by X39


Recently checked the different sources again and noticed: i got various questions about XInsurgency, ArmA-UI-Editor, ...

soooo ... why are all theese things "dead"?

well ... first of all: they are not dead, they are on hold. Currently, there are higher priorities then a free non-money bringing hobby ...

what does that mean?

I am currently busy ... and cannot work on my projects :3

i do when i find spare time ... but most things are just waaaayyy to big to simply throw out an update here and there .. do not worry ... i will continue sooner or later ... but right now ... there is simply no way for me to spend more time in my hobby

kindly regards, X39