initial commit

This commit is contained in:
Jan Wolff 2022-11-05 20:00:03 +01:00
commit f6b4208301
116 changed files with 1156 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
.devcontainer/
.hugo_build.lock
/public/
/resources/_gen/
/assets/jsconfig.json
hugo_stats.json

6
archetypes/default.md Normal file
View file

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

25
config.toml Normal file
View file

@ -0,0 +1,25 @@
baseURL = 'https://janw.name/'
languageCode = 'en-us'
title = 'janw.name'
theme = 'janw'
[params]
subtitle = 'Personal Blog and Portfolio of Jan Wolff'
[menu]
[[menu.main]]
name = 'Home'
url = '/'
weight = 1
[[menu.main]]
name = 'Blog'
url = '/posts/'
weight = 100
[[menu.main]]
name = 'About Me'
url = '/about/'
weight = 110
[[menu.main]]
name = 'Projects'
url = '/projects/'
weight = 120

7
content/_index.md Normal file
View file

@ -0,0 +1,7 @@
---
title: "Home"
date: 2022-10-01T18:46:54Z
draft: true
---
Hi! Im Jan (he/him). You can find some of the stuff that I made on this website!

6
content/about/_index.md Normal file
View file

@ -0,0 +1,6 @@
---
title: "About"
date: 2022-10-01T19:00:12Z
draft: true
---

66
content/legal/_index.md Normal file
View file

@ -0,0 +1,66 @@
---
title: "Legal Disclaimer"
date: 2022-10-08T17:02:00Z
draft: true
---
## Disclaimer
I don't feel comfortable handing out my full address here. Please just send
a mail `contact (at) jancc (point) de` and we can discuss anything.
### Limitation of liability for internal content
The content of our website has been compiled with meticulous care and to the
best of our knowledge. However, we cannot assume any liability for the
up-to-dateness, completeness or accuracy of any of the pages.
Pursuant to section 7, para. 1 of the TMG (Telemediengesetz Tele Media Act by
German law), we as service providers are liable for our own content on these
pages in accordance with general laws. However, pursuant to sections 8 to 10 of
the TMG, we as service providers are not under obligation to monitor external
information provided or stored on our website. Once we have become aware of a
specific infringement of the law, we will immediately remove the content in
question. Any liability concerning this matter can only be assumed from the
point in time at which the infringement becomes known to us.
### Limitation of liability for external links
Our website contains links to the websites of third parties („external links“).
As the content of these websites is not under our control, we cannot assume any
liability for such external content. In all cases, the provider of information
of the linked websites is liable for the content and accuracy of the
information provided. At the point in time when the links were placed, no
infringements of the law were recognisable to us. As soon as an infringement of
the law becomes known to us, we will immediately remove the link in question.
### Copyright
The content and works published on this website are governed by the copyright
laws of Germany. Any duplication, processing, distribution or any form of
utilisation beyond the scope of copyright law shall require the prior written
consent of the author or authors in question.
### Data protection
A visit to our website can result in the storage on our server of information
about the access (date, time, page accessed). This does not represent any
analysis of personal data (e.g., name, address or e-mail address). If personal
data are collected, this only occurs to the extent possible with the prior
consent of the user of the website. Any forwarding of the data to third parties
without the express consent of the user shall not take place.
We would like to expressly point out that the transmission of data via the
Internet (e.g., by e-mail) can offer security vulnerabilities. It is therefore
impossible to safeguard the data completely against access by third parties. We
cannot assume any liability for damages arising as a result of such security
vulnerabilities.
The use by third parties of all published contact details for the purpose of
advertising is expressly excluded. We reserve the right to take legal steps in
the case of the unsolicited sending of advertising information; e.g., by means
of spam mail.
Source:
[Mustervorlage.net](http://www.mustervorlage.net/disclaimer-muster#Englisch)

View file

@ -0,0 +1,32 @@
---
title: "Ephemeral Downloads"
date: 2019-09-19T09:27:04Z
draft: true
---
This is just a quick tipp. I added the following line to my `/etc/fstab` file:
tmpfs /home/jan/Downloads tmpfs rw,nodev,noexec,size=1G 0 0
It mounts my downloads directory onto an in-memory filesystem. This effectively
makes my downloads only stay in RAM. I had the problem in the past that this
directory would balloon in size because I'd never clean it. Now it will always
be cleaned on reboot because RAM can't hold data without being powered.
It has some other useful side effects too. As you may noticed there are some
other flags added to the mount. `nodev` is obvious. `noexec` makes it
impossible to execute anything in this folder. When I'm downloading binaries
in order to execute them I want to force myself into moving them somewhere else
first. Also while writing this... `nosuid` is kinda redundant now, isn't it? Oh
well.
The size is limited to a single gigabyte. Larger files should likely be
archived somewhere else directly, because I don't want to download those
multiple times. Is is no problem, by the way, to overprovision the mount's
size. It does not reserve the full size on memory, but it grows dynamically.
Therefore you could extend this idea onto many more mountpoints.
Theoretically this is also a great solution should your net-connection be
faster than your hard drive's write speed. But I live in Germany so this isn't
something I'd need to ever worry about lol.

View file

@ -0,0 +1,220 @@
---
title: "Setting up a WireGuard VPN"
date: 2021-09-28T17:53:09Z
draft: true
---
In this post I want to give a quick rundown of the few steps required to use
[WireGuard](https://www.wireguard.com/) as a VPN. My setup uses a Raspberry Pi
running [Arch Linux ARM](https://archlinuxarm.org/) as the main gateway into my
home network. I'll configure another peer such that it can connect to the Pi
and thus other devices in my network. The setup is IPv4-only at the moment
because my ISP sucks. Also you should have some prior knowledge in networking.
## First steps
As ArchLinux ARM (in its default configuration) ships with a Linux kernel with
WireGuard support enabled, the first step is to install WireGuard's userland
tools.
$ pacman -S wireguard-tools
Naturally the package is not called `wireguard-tools` on every platform. A
complete list of packages for different operating systems can be found
[here](https://www.wireguard.com/install/). This gives you access to the `wg`
utility, which can perform several management tasks and the `wg-quick` utility,
which can load and apply configurations from files. I'll not be making much use
of in-place configuration and instead jump directly into writing configuration
files, as they are pretty straightforward regardless. All configuration files
live in `/etc/wireguard`. They could be located anywhere but this path allows
shorthand notation in `wg-quick` arguments.
### Server
First let's set up the server (i.e. the Raspberry Pi), which the client can
then connect with in order to have a tunneled connection into my home network.
Create a configuration file in `/etc/wireguard/` called `wg0.conf`. Set its
mode to `0600` because it will contain a private key and therefore shouldn't be
world-readable. The configuration syntax is somewhat similar to Windows' INI
files. The server's interface is configured like this:
[Interface]
Address = 192.168.42.1/24
ListenPort = 50040
PrivateKey = RG9udCB1c2UgdGhpcyB2YWx1ZSB5b3UgZHVtYmFzcyE=
MTU = 1420
`Address` refers to the server's address within the WireGuard tunnel. In my
setup I wanted to have the WireGuard "network" live under the netmask
`192.168.42.0/24`. Having the main gateway be `192.168.42.1` makes things
simple to understand. `ListenPort` is `50040` but can be anything of course
(I'm not even sure there is a definite default yet). Setting `MTU` to `1420` is
the default and should work pretty much everywhere. Most interesting is the
`PrivateKey` field. WireGuard uses Ed25519 keys for authentication and this is
simply the server's identity. The value can be generated via `wg genkey`.
And that's is on the server side for now. You can call `wg-quick up wg0` to
enable this interface right now and verify its existence via the output of `ip
link` and `ip address` commands.
### Client
Now for the same on the client.
[Interface]
Address = 192.168.42.2/24
ListenPort = 50041
PrivateKey = TmV2ZXIgZXZlciBjb3B5IGtleXMgZnJvbSBndWlkZXM=
MTU = 1420
No surprises here. The client also has a private key and its IP is to be
`192.168.42.2`. The `ListenPort` should be different to the server's port, as
WireGuard should be able to establish connections in both directions.
### Peering
Now we'll connect client and server. To make this work we'll need to exchange
keys, as the server needs to know the client's public key and vice versa. The
command `wg pubkey` can be used to derive the public key from the private key.
For example, to get the server's public key:
$ echo "RG9udCB1c2UgdGhpcyB2YWx1ZSB5b3UgZHVtYmFzcyE=" | wg pubkey
QXJlIHlvdSByZWFkaW5nIHRoaXM/IEZvciByZWFsPyA=
(Sidenote: This will write the private key into your shell history. So you may
want to write the key into a file instead and `cat` it's contents into `wg
pubkey`)
While not strictly required, you may also generate and exchange a _pre-shared
key_ between the peers, such that you also benefit from a layer of symmetric
cryptography in case you want to harden against quantum cryptanalysis. Such
a key can be generated via `wg genpsk`:
$ wg genpsk
eW91IGNvdWxkIGFjdHVhbGx5IHVzZSB0aGlzIG9uZSA=
Both the client's and the server's configuration needs an additional `[Peer]`
section now.
For the server this section needs to look like this:
[Peer]
PublicKey = a2V5c21hc2hrZXlzbWFzaGtleXNtYXNoa2V5c21hc2g=
PresharedKey = eW91IGNvdWxkIGFjdHVhbGx5IHVzZSB0aGlzIG9uZSA=
AllowedIPs = 192.168.42.2/32
And for the client like this:
[Peer]
PublicKey = QXJlIHlvdSByZWFkaW5nIHRoaXM/IEZvciByZWFsPyA=
PresharedKey = eW91IGNvdWxkIGFjdHVhbGx5IHVzZSB0aGlzIG9uZSA=
AllowedIPs = 192.168.42.1/32
Endpoint = vpn-host.example:50040
Notice the additional `Endpoint` value in the client. This is because the
client obviously needs to know where the server is located such that a
WireGuard tunnel can be established. This does not need to be a domain name and
could instead just be a raw IP address. Of course, in a VPN setup there is no
way we could know an `Endpoint` value for the client. The server will learn the
client's endpoint after each handshake, which is implicitly performed whenever
the client starts to send data to the server.
...aaand that's it! Do `wg-quick up wg0` on both devices and try to perform a
ping over the WireGuard tunnel. You can inspect the state of the tunnel via:
$ wg
## VPN
Our devices can now talk to _each other_ over WireGuard. But that is not
enough, as the aim is to allow routing traffic into my home network. I don't
care about routing connections to the internet over WireGuard and simply want
my client to be able to access devices on the `192.168.0.0/24` network (i.e. my
home network).
We're way more than halfway there. The last two puzzle pieces are: IP
forwarding, routing and having traffic from the client to `192.168.0.0/24` move
through WireGuard.
### IP Forwarding
On Linux, routing can be enabled through `sysctl`:
$ sysctl -w net.ipv4.ip_forward=1
To make this setting stick at boot, write this setting into a file in the
directory `/etc/sysctl.d`:
$ echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ip-forwarding.conf
### Routing
Routing, or to be more precise _masquerading_, can be enabled via `iptables`:
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
`eth0` needs to be replaced with the canonical name of your server's network
interface.
This can also be automated via WireGuard's configuration manager, which is able
to execute commands when an interface is enabled and disabled. Add the command
into the `PostUp` option in the `[Interface]` section:
[Interface]
(...)
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
`PostDown` removes this when the WireGuard interface is disabled.
### Traffic to 192.168.0.0/24
This is added to the client's configuration. Remember the `AllowedIPs` key in
the `[Peer]` section? You can simply add the whole network like this:
[Peer]
(...)
AllowedIPs = 192.168.42.1/32, 192.168.0.0/24
That's it. `wg-quick` will set up the routes accordingly.
## And?
That's it. You're done. Enjoy your VPN :)
## Persistent Keepalive
This is a small update after a few months of very successfully using WireGuard.
You might find yourself in the following situation: Consider that you have two
devices, _A_ and _B_, on your network. _A_ has the address `192.168.42.2` and
_B_ has the address `192.168.42.3`. Your router and gateway is at
`192.168.42.1`. `wg-quick` sets routing up for you, simply sending all traffic
towards `192.168.42.0/24` over your router. Sure you _could_ configure a direct
connection between each and every peer manually, but this would get super
annoying super fast.
Device A might be... whatever. And device B might be some gizmo that you only
boot up sporadically via Wake-on-LAN. You'll find that, once B is booted up, A
has no idea how to talk to B. The router doesn't know that B is awake yet. And
B never had any reason to communicate with the router. So the router won't have
any clue how to route A's traffic to B. Remember how WireGuard is advertised as
not being a talky protocol by default? This is exactly that principle in action
and in most cases its perfectly fine. However here it falls flat on its face.
What we need to do here, is make sure that the router always knows how to talk
to B and that it maintains a route.
For this end, we can simply add the following line to _B_'s `wg.conf`:
[Peer]
(...)
PersistentKeepalive = 30
Now B will say "hello" to the router every 30 seconds, thus allowing the router
to know of B's existence. You can, of course, also choose a higher interval.
Most important is the initial handshake from B to the router right after B has
finished booting up.
And this concludes one of the few cases in which you should add
`PersistentKeepalive` to your WireGuard configurations. Seriously, if you
don't encounter any issues just leave it out.

View file

@ -0,0 +1,113 @@
---
title: "Collecting the DLLs Required by an MSYS2 Binary"
date: 2022-04-21T09:27:15Z
draft: true
---
After many unsuccessful attempts of writing a third blog post, I just wanted to
use this opportunity to share something useful I found after dabbling with
porting an _SDL2_ app to _Windows_ via _MSYS2 MinGW x64_.
TL;DR: You can collect all the _MinGW_ DLLs your EXE file needs like this:
ldd my-cool-program.exe | grep /mingw64 | awk '{print $3}' | xargs -i cp {} .
You see, in the magical Linux realm you'll never really worry about shipping
programs in binary form. A nice tarball with a well documented build system is
often regarded as good enough. If your program is actually used by people, its
likely that distributions pick it up into their repositories. Or you use stuff
like _Flatpak_ or _AppImage_ if you want to provide binaries yourself. But
over in Windows-land providing .exe files is a normal part of distributing your
programs.
Now, if you use any special libraries they are often dynamically linked and
their code is stored externally to your .exe as a .dll. Some .dll files are
simply stored somewhere in System32 and are thus available everywhere, but
others have to be shipped manually alongside your program.
---
Now let me go over a short tangent praising the efforts the developers of
_MinGW64_ have made. I wrote a little game in C using Lua and SDL2. On Linux,
building that game was simple. I'd use GNU/Make, _pkg-config_ and my distro's
package manager to collect the dependencies and tie everything together. I'd
dreaded the Windows port but eventually gave it a shot. And holy shit. _MSYS2_
provides EXACTLY THE SAME workflow!
The packages' names are a bit more arcane sounding (e.g.:
`mingw-w64-x86_64-gcc`, `mingw-w64-x86_64-SDL2`, `mingw-w64-x86_64-lua`),
because MSYS2 provides multiple toolchains and thus the packages have to be
more explicit in their naming. But after installing everything and running
`make` I had a working .exe file! Well... It was working after I fixed a
segfault that I didn't catch under Linux anyways. But that one's on me.
Running the .exe in MSYS2's shell worked fine, but starting it outside of the
shell resulted in most DLLs being unavailable. That's because, all non-system
DLLs are not provided to the program by default. That includes stuff like Lua's
or SDL2's DLL files. They are stored in the path `/mingw64/bin/`. Now, you
COULD go ahead and manually copy them, but why do that when that task can be
automated?
---
MinGW64 provides a version of the `ldd` program, which spits out all the
dynamically linked libraries required by a program. Its output may look
something like this:
$ ldd my-cool-game.exe
ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x7ffa09e30000)
KERNEL32.DLL => /c/Windows/System32/KERNEL32.DLL (0x7ffa09d30000)
KERNELBASE.dll => /c/Windows/System32/KERNELBASE.dll (0x7ffa075f0000)
msvcrt.dll => /c/Windows/System32/msvcrt.dll (0x7ffa08c00000)
SHELL32.dll => /c/Windows/System32/SHELL32.dll (0x7ffa08cb0000)
msvcp_win.dll => /c/Windows/System32/msvcp_win.dll (0x7ffa07550000)
ucrtbase.dll => /c/Windows/System32/ucrtbase.dll (0x7ffa07d90000)
USER32.dll => /c/Windows/System32/USER32.dll (0x7ffa09690000)
win32u.dll => /c/Windows/System32/win32u.dll (0x7ffa07d60000)
GDI32.dll => /c/Windows/System32/GDI32.dll (0x7ffa08a50000)
gdi32full.dll => /c/Windows/System32/gdi32full.dll (0x7ffa078c0000)
SDL2_mixer.dll => /mingw64/bin/SDL2_mixer.dll (0x7ff9f7fd0000)
lua54.dll => /mingw64/bin/lua54.dll (0x7ff9f0e80000)
libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x7ff9f7210000)
SDL2.dll => /mingw64/bin/SDL2.dll (0x7ff9e39f0000)
(...)
Most referenced DLLs reside in Window's System32 folder. They are provided by
the system and will always be there. So you don't have to worry about providing
them. The DLLs in `/mingw64/bin/...` however need to be placed alongside your
.exe file if people should be able to run your game via double-clicking it.
Cool, so that's where our automation can begin! First step is super simple:
let's filter out the non-system DLLs using `grep`:
ldd my-cool-program.exe | grep /mingw64
Might not be _super_ robust, but I _highly_ doubt that the string "/mingw64"
will ever show up in a Windows system DLL's path.
Next, we only care about the DLL's path. So we use `awk` to cut out that
portion of the lines. If we regard the spaces as delimiting characters of text
columns, the full path is in the third column (The first is just the filename,
and the second is "=>"). The `awk` command `awk {print $3}` gives us this third
column, so we can just append it to our shell command:
ldd my-cool-program.exe | grep /mingw64 | awk '{print $3}'
By now, our shell command spits our a list of full paths of all non-system DLLs
dynamically linked to our program. Cool! But we want to automate the whole
thing, so lets add a final call to `xargs`, to copy all files in this list into
our current directory. Here, I'll use `xargs -i cp {} .`. The `-i cp {} .`
parameter means that, for every file in the list, we call `cp`, pass the DLL's
path as the first parameter and the target directory `.` as the second
parameter.
Here is the final call:
ldd my-cool-program.exe | grep /mingw64 | awk '{print $3}' | xargs -i cp {} .
---
Cool! Now go put this in your CI script and automate packaging your Windows
releases. Or, if you're like me, make exactly one release and wonder why you
spent so much time on figuring this out when you could have just collected the
files manually once and then forget about it ARGH

5
content/posts/_index.md Normal file
View file

@ -0,0 +1,5 @@
---
title: "Blog"
date: 2022-10-01T18:55:23Z
draft: true
---

6
content/projects/500m.md Normal file
View file

@ -0,0 +1,6 @@
---
title: "500m"
date: 2022-10-08T17:21:27Z
draft: true
---

View file

@ -0,0 +1,7 @@
---
title: "Projects"
date: 2022-10-01T19:00:22Z
draft: true
---
Things I've made.

View file

@ -0,0 +1,6 @@
---
title: "A Dark Dawn"
date: 2022-10-08T17:21:31Z
draft: true
---

View file

@ -0,0 +1,8 @@
---
title: "Anti-Smoke Man"
date: 2011-04-01T08:33:34Z
teaser: /projects/besmart/screenshot104.png
draft: true
---
lol

View file

@ -0,0 +1,6 @@
---
title: "Cybernator"
date: 2022-10-08T17:21:11Z
draft: true
---

View file

@ -0,0 +1,6 @@
---
title: "Death Typer"
date: 2022-10-08T17:21:46Z
draft: true
---

View file

@ -0,0 +1,6 @@
---
title: "Duckalypse"
date: 2022-10-08T17:21:18Z
draft: true
---

View file

@ -0,0 +1,8 @@
---
title: "Godscythe"
date: 2020-02-29T08:33:34Z
teaser: /projects/godscythe/godscythe0.jpg
draft: true
---
lol

7
content/projects/lost.md Normal file
View file

@ -0,0 +1,7 @@
---
title: "Lost Projects"
date: 2022-10-08T17:22:31Z
teaser: /projects/pics/house_of_doom.png
draft: true
---

View file

@ -0,0 +1,6 @@
---
title: "Outer Earth Arena"
date: 2022-10-08T17:22:00Z
draft: true
---

View file

@ -0,0 +1,7 @@
---
title: "Raum Race"
date: 2022-10-08T17:22:15Z
teaser: /projects/raum_race/screenshot101.png
draft: true
---

View file

@ -0,0 +1,10 @@
<footer class="big-container">
<p>
Copyright 2013-{{ now.Year }} Jan Wolff. All trademarks and trademarked contents are the properties of their respective owners.
All other content, except where noted, is licensed under a
<a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.
</p>
<p>
Refer to the <a href="/legal">legal disclaimer</a> for more information.
</p>
</footer>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 840 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<title>Godscythe Trailer</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
video {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
}
</style>
</head>
<body>
<video controls>
<source src="trailer.webm" type="video/webm">
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,018 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show more