<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Molly Crendraven</title>
    <description>The latest articles on DEV Community by Molly Crendraven (@drazisil).</description>
    <link>https://dev.to/drazisil</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F24630%2F0557c662-6773-4872-8d86-667a11a56de4.png</url>
      <title>DEV Community: Molly Crendraven</title>
      <link>https://dev.to/drazisil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/drazisil"/>
    <language>en</language>
    <item>
      <title>Using JSDoc in VSCode Without Import()</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Sat, 23 Dec 2023 07:01:59 +0000</pubDate>
      <link>https://dev.to/drazisil/using-jsdoc-in-vscode-without-import-4cpm</link>
      <guid>https://dev.to/drazisil/using-jsdoc-in-vscode-without-import-4cpm</guid>
      <description>&lt;p&gt;Look, It's another click-bait title. Guess what? It gets even worse. This isn't even my nugget of information. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/a/48455477/335583"&gt;https://stackoverflow.com/a/48455477/335583&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's 100% courtesy of &lt;a href="https://stackoverflow.com/users/4408546/jeremy"&gt;https://stackoverflow.com/users/4408546/jeremy&lt;/a&gt;. For real, please go show that post some love.&lt;/p&gt;

&lt;p&gt;This is more for me, and to try that whole "share as you learn" concept I'm really bad at.&lt;/p&gt;

&lt;p&gt;Now that I've got all my disclamers covered...&lt;/p&gt;

&lt;p&gt;I must be the only person on the planet who really doesn't like Microsoft's style of JSDoc support in VSCode. Because whenever I look for "Make JSDoc work with Intelisense" I get "just use &lt;code&gt;import()&lt;/code&gt; in the tag!"&lt;/p&gt;

&lt;p&gt;Ok, but there's a problem. &lt;code&gt;import()&lt;/code&gt; is strictly a Microsoft thing, and is not valid JSDoc. JSDoc crashes when it sees it. Plus, it's ugly. Why it doesn't support &lt;code&gt;module:&lt;/code&gt; like the docs say is the way? 🤷&lt;/p&gt;

&lt;p&gt;But, if you don't use &lt;code&gt;import()&lt;/code&gt;, VSCode will mark eveything as "any".&lt;/p&gt;

&lt;p&gt;Unless... you happen to have stumbled, after years of searching, on this answer:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--28U1ki75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qgq86b9shl1tfp28rp03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--28U1ki75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qgq86b9shl1tfp28rp03.png" alt='Export your interfaces and types normally, using a .d.ts file. Then, at the end of the file, add "export as namespace YOUR_NAMESPACE_HERE" New you can access them in any file as a property of the namespace.' width="667" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it works! Please, go show &lt;a href="https://stackoverflow.com/a/48455477/335583"&gt;https://stackoverflow.com/a/48455477/335583&lt;/a&gt; some love!&lt;/p&gt;

</description>
      <category>jsdoc</category>
      <category>vscode</category>
      <category>learninginpublic</category>
    </item>
    <item>
      <title>gdbus --system Can't connect?</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Sun, 06 Aug 2023 15:17:10 +0000</pubDate>
      <link>https://dev.to/drazisil/gdbus-system-cant-connect-44fm</link>
      <guid>https://dev.to/drazisil/gdbus-system-cant-connect-44fm</guid>
      <description>&lt;p&gt;I was uninstalling some orphan packaged on my Arch-based Manjaro Linux system when I noticed something strange...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Error connecting: Could not connect: No such file or directory&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The uninstall seemed to work correctly, but what was this error? I went looking for the logs...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[2023-08-05T09:33:35-0400] [ALPM] running '90-packagekit-refresh.hook'...
[2023-08-05T09:33:35-0400] [ALPM-SCRIPTLET] Error connecting: Could not connect: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Huh. Well, the last thing that &lt;code&gt;pacman&lt;/code&gt; tried before the error was calling &lt;code&gt;90-packagekit-refresh.hook&lt;/code&gt;. Let's ask &lt;code&gt;man pacman&lt;/code&gt; what a hook is.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;--hookdir &lt;/p&gt;
&lt;br&gt;
           Specify a alternative directory containing hook files (the default is /etc/pacman.d/hooks).&lt;br&gt;
           Multiple hook directories can be specified with hooks in later directories taking precedence over&lt;br&gt;
           hooks in earlier directories.  NOTE: This is an absolute path, and the root path is not&lt;br&gt;
           automatically prepended.&lt;br&gt;

&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls /etc/pacman.d/hooks                                                     

ls: cannot access '/etc/pacman.d/hooks': No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's weird, the default directory doesn't seem to exist. Normally, I'd think this was the issue, except that pacman appeared to run many other hooks with no issues. So, where else are the hooks? &lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://wiki.archlinux.org/title/Pacman"&gt;https://wiki.archlinux.org/title/Pacman&lt;/a&gt;, section 2.1.8, hooks generally live in &lt;code&gt;/usr/share/libalpm/hooks&lt;/code&gt;. That directory does exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /usr/share/libalpm/hooks/90-packagekit-refresh.hook

[Trigger]
Type = Package
Operation = Install
Operation = Upgrade
Operation = Remove
Target = *

[Action]
Description = Refreshing PackageKit...
When = PostTransaction
Exec = /bin/sh -c 'gdbus call --system --timeout 30 --dest org.freedesktop.PackageKit --object-path /org/freedesktop/PackageKit --method org.freedesktop.PackageKit.StateHasChanged posttrans &amp;gt; /dev/null'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seems pretty straightforward. Let's first confirm this is the issue. I made a backup of the file and deleted it. No more error. Ok, so what is PackageKit?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freedesktop.org/software/PackageKit/pk-intro.html"&gt;https://www.freedesktop.org/software/PackageKit/pk-intro.html&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Formally, PackageKit is a D-Bus abstraction layer that allows the session user to manage packages in a secure way using a cross-distro, cross-architecture API. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nifty. I probably don't want to remove it. Let's reinstall it. Maybe it's broken.&lt;/p&gt;

&lt;p&gt;That put both the file, and the error back. Doesn't seem to be specifically PackageKit related.&lt;/p&gt;

&lt;p&gt;What's DBus? I know it's pretty important, but I don't know what it is...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freedesktop.org/wiki/Software/dbus/"&gt;https://www.freedesktop.org/wiki/Software/dbus/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;D-Bus is a message bus system, a simple way for applications to talk to one another. In addition to interprocess communication, D-Bus helps coordinate process lifecycle; it makes it simple and reliable to code a "single instance" application or daemon, and to launch applications and daemons on demand when their services are needed. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nice. It's how the different parts of Linux send events to each other. So I can probably safely call this command myself. I'll drop the redirect to /dev/null, and I don't need to pass the command to bash so,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gdbus call --system --timeout 30 --dest org.freedesktop.PackageKit --object-path /org/freedesktop/PackageKit --method org.freedesktop.PackageKit.StateHasChanged posttrans

Error connecting: Could not connect: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That looks familiar. Let's remove parts until we get down to what is throwing the error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gdbus call --system

Error connecting: Could not connect: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow. We can't send commands to the system message bus. That sounds...impossible? &lt;/p&gt;

&lt;p&gt;There's also a &lt;code&gt;--session&lt;/code&gt; bus. That one works. So dbus isn't 100% broken. Wouldn't you know, this is the only hook that calls dbus.&lt;/p&gt;

&lt;p&gt;I want a dbus viewer. Where's my system bus, and what's on it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qdbus --system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, that's interesting. Seems I have a system bus, and there's a lot of things on it. This text dump is herd to read, can I get a visual?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;qdbusviewer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lIBXljfe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ns90zq81f6dwkhbmr1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lIBXljfe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ns90zq81f6dwkhbmr1s.png" alt="Screenshot of QDBusViewer, showing that the posttrans command can be successfully sent to the org.freedesktop.PackageKet's StateHasChanged method on the system bus" width="800" height="774"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, I can send the exactly same command though this tool. There's nothing wrong with my system bus. Why can't &lt;code&gt;gdbus&lt;/code&gt; connect to it? Where does &lt;code&gt;gdbus&lt;/code&gt; come from?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pacman -Qo gdbus

/usr/bin/gdbus is owned by glib2 2.76.4-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Part of glib. I can work with that. Starting at &lt;a href="https://gitlab.gnome.org/GNOME/glib/-/blob/e8af76ad250a2bb6d5cb18aec056efbc18fb2fb2/gio/gdbus-tool.c"&gt;https://gitlab.gnome.org/GNOME/glib/-/blob/e8af76ad250a2bb6d5cb18aec056efbc18fb2fb2/gio/gdbus-tool.c&lt;/a&gt; I trace the code until I reach the &lt;code&gt;Error connecting&lt;/code&gt; message on line 685. Looking us a few lines, it seems I need a unix: socket. Going to ask the task manager what socket the &lt;code&gt;dbus-daemon&lt;/code&gt; is listening to.&lt;/p&gt;

&lt;p&gt;It seems to be &lt;code&gt;/run/user/1000/at-spi/bus_0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://gitlab.gnome.org/GNOME/glib/-/blob/main/gio/gdbusaddress.c#L1313"&gt;https://gitlab.gnome.org/GNOME/glib/-/blob/main/gio/gdbusaddress.c#L1313&lt;/a&gt;, that's my session bus. Maybe the system bus is in the same dir? I know sockets tend to live in &lt;code&gt;/run/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Turns out, that's the only file there. Maybe that's why gdbus can't find the system bus socket. But we know there is one somewhere, and that it's working. Time for the big toys&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo strace gdbus call --system 2&amp;gt;&amp;amp;1 | tee  out.log&lt;/code&gt;1&lt;/p&gt;

&lt;p&gt;I love &lt;code&gt;strace&lt;/code&gt;. It will show you every. single. thing that a program is trying to do and is amazing at hunting down "I can't find x" errors. Looks like we are trying to open a socket at...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;connect(5, {sa_family=AF_UNIX, sun_path="/home/linuxbrew/.linuxbrew/var/run/dbus/system_bus_socket"}, 110) = -1 ENOENT (No such file or directory)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Linuxbrew? That doesn't seem right. Why would something that's a core part of glib be looking for a socket in the homebrew directory?? No big surprise, said socket doesn't exist either.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew list

dbus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have dbus installed via homebrew??&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew remove dbus`

dbus is required by deno
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew remove deno
brew remove dbus
gdbus call --system

Needs more arguments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sudo strace gdbus call --system 2&amp;gt;&amp;amp;1 | tee  out.log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ohhh. There it is,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;connect(5, {sa_family=AF_UNIX, sun_path="/run/dbus/system_bus_socket"}, 110) = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for reading this far. If you guessed that things now work as expected, with no weird connection errors in package actions, you get a cookie. Hope this helps you troubleshoot weird things in the future, Keep #LearningInPublic!&lt;/p&gt;

&lt;p&gt;[&lt;a&gt;1&lt;/a&gt;] &lt;a href="https://web.archive.org/web/20230325170159/https://www.shellhacks.com/redirect-stderr-to-stdout/"&gt;https://web.archive.org/web/20230325170159/https://www.shellhacks.com/redirect-stderr-to-stdout/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pacman</category>
      <category>archlinux</category>
      <category>dbus</category>
      <category>learninginpublic</category>
    </item>
    <item>
      <title>Generating GPG keys with Windows 11 and WSL</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Fri, 16 Dec 2022 00:32:08 +0000</pubDate>
      <link>https://dev.to/drazisil/generating-gpg-keys-with-windows-11-and-wsl-31d5</link>
      <guid>https://dev.to/drazisil/generating-gpg-keys-with-windows-11-and-wsl-31d5</guid>
      <description>&lt;p&gt;Are you encountering an issue where the pinentry prompt for a GPG key generation in Windows Subsystem for Linux (WSL) is stuck in a loop. Is it doing this regardless of the &lt;code&gt;DISPLAY&lt;/code&gt; you set, or the &lt;code&gt;pinentry-&lt;/code&gt; programs you try and install? Good news. While you still have hair (or sanity, if you are already bald), you can generate the GPG keys on the Windows side and copy them over. &lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the generation command in a git bash terminal&lt;/li&gt;
&lt;li&gt;Copy the &lt;code&gt;.gnupg&lt;/code&gt; directory from your Windows user directory, to your WSL user directory, using the WSL entry in the Windows Explorer. You can safely skip any conflicts.&lt;/li&gt;
&lt;li&gt;Success!&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Nested subcommands in Rest with clap</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Tue, 24 May 2022 02:13:52 +0000</pubDate>
      <link>https://dev.to/drazisil/nested-subcommands-in-rest-with-clap-4n5m</link>
      <guid>https://dev.to/drazisil/nested-subcommands-in-rest-with-clap-4n5m</guid>
      <description>&lt;p&gt;I apologize for the brief post, but it's late and I spent too much time figuring this out to not share. Hope it helps someone!&lt;/p&gt;

&lt;p&gt;Edit: I have no ideas why repl.it won't find the traits and compile. I swear it works in real life. Suggestions for fixing the example are welcome!&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@drazisil/Nested-subcommand-in-Relp-with-clap?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


</description>
      <category>rust</category>
      <category>cli</category>
      <category>clap</category>
    </item>
    <item>
      <title>Debugging User has disconnected, reason: Timed out</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Thu, 02 Apr 2020 19:48:26 +0000</pubDate>
      <link>https://dev.to/drazisil/debugging-user-has-disconnected-reason-timed-out-emk</link>
      <guid>https://dev.to/drazisil/debugging-user-has-disconnected-reason-timed-out-emk</guid>
      <description>&lt;p&gt;Note: This is being approached from the side of the server operator, not the user.&lt;/p&gt;

&lt;p&gt;There are many answers to how to troubleshoot the Minecraft &lt;code&gt;User has disconnected, reason: Timed out&lt;/code&gt; message, they all boil down to "your internet is bad", "your server's tick is bad", your server is bad", &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;, or, even better, "I fixed it!" &lt;sup&gt;&lt;a href="https://xkcd.com/979/"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My server has a great network connection, and is running at 20 TPS&lt;/li&gt;
&lt;li&gt;The user trying to connect has a 3-digit ping. Over 100, but not high enough to cause issues, imo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What causes this error? There is actually only thing in Minecraft that can cause the exact &lt;code&gt;User has disconnected, reason: Timed out&lt;/code&gt; message, and that is failure to receive a Keep Alive packet from the client in the expected time, or the other way around. &lt;sup&gt;&lt;a href="https://github.com/search?q=TranslationTextComponent%28%22disconnect.timeout%22%29&amp;amp;type=Code"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Based on this, we would think this is probably a network issue. Unfortunately, by default, Minecraft does not output logs at a level lower then INFO. In order to troubleshoot, we need DEBUG level. How to get these?&lt;/p&gt;

&lt;p&gt;Minecraft uses Log4j for logging. Thankfully, it is easy to override the configuration at runtime by passing a file containing new settings as part of the java arguments.&lt;/p&gt;

&lt;p&gt;Let's start with the default log4j config &lt;sup&gt;&lt;a href="https://gist.github.com/drazisil/e82b7dc151593dee4d0b4518958cea42"&gt;2&lt;/a&gt;&lt;/sup&gt; for Minecraft (this is the same for both client and server sides.&lt;/p&gt;

&lt;p&gt;In order to change to DEBUG level, we need to edit &lt;code&gt;&amp;lt;Root level="info"&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;Root level="debug"&amp;gt;&lt;/code&gt;. We also need to remove the &lt;code&gt;&amp;lt;filters&amp;gt;&lt;/code&gt; section, which is dropping all network packets, regardless of level. Finally, since we are dealing with connection times, I've modified the timestamp to &lt;code&gt;%d{HH:mm:ss.SSS}&lt;/code&gt;, to show milliseconds. &lt;/p&gt;

&lt;p&gt;Once you save your modified config file &lt;sup&gt;&lt;a href="https://gist.github.com/drazisil/cfe81fe4cacf2500f465298a209f1cec"&gt;3&lt;/a&gt;&lt;/sup&gt; somewhere, you need to tell Minecraft to use it. To do so, add the following option to your java command, &lt;code&gt;-Dlog4j.configurationFile=File:/home/drazisil/log4j_minecraft.xml&lt;/code&gt;, changing the path to point to the full path and filename you chose.&lt;/p&gt;

&lt;p&gt;I recommend trying this on the client who is having trouble first., assuming you can reproduce the issue, or they are willing to troubleshoot with you. You are looking for log lines like the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[14:16:40.945] [Netty Epoll Client IO #0/DEBUG]:  IN: [PLAY:21] ms&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[14:16:40.947] [Netty Epoll Client IO #0/DEBUG]: OUT: [PLAY:15] qb&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the packet ids, and the Minecraft class names. You can get the packet ids from &lt;a href="https://wiki.vg"&gt;https://wiki.vg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this instance we can see that my client received the client-bound Keep Alive packet (21) at 14:16:40.945, and responded with a server-bound Keep Alive packet (15) at 14:16:40.947, 2 milliseconds later. Pretty good, so we know this isn't a client CPU issue. The next step would be to repeat the process on the server end and see if the server received the packet in that same time.&lt;/p&gt;

&lt;p&gt;Hope this helps, and any questions or feedback, hit me up. (no, I will not help you troubleshoot individual cases) ;)&lt;/p&gt;

</description>
      <category>minecraft</category>
      <category>logs</category>
      <category>troubleshooting</category>
    </item>
    <item>
      <title>Bare metal load balancer on Kubernetes with MetalLB</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Mon, 16 Sep 2019 01:01:13 +0000</pubDate>
      <link>https://dev.to/drazisil/bare-metal-load-balancer-on-kubernetes-with-metallb-3h2k</link>
      <guid>https://dev.to/drazisil/bare-metal-load-balancer-on-kubernetes-with-metallb-3h2k</guid>
      <description>&lt;p&gt;Part two of a mini series, the first part is here &lt;a href="https://dev.to/drazisil/setting-up-kubernetes-on-bare-metal-behind-a-nat-with-openvpn-5dj3"&gt;1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that I have a working Kubernetes cluster on bare metal, the next thing I wanted was to get external traffic into it without the need for &lt;code&gt;kubectl proxy&lt;/code&gt;. Using the API path to access sites like the dashboard seems silly.&lt;/p&gt;

&lt;p&gt;The cleanest way to get traffic into a cluster seems to be a load balancer. However, it requires an external service usually provided by GCP or AWS that doesn't come with Kubernetes. What to do?&lt;/p&gt;

&lt;p&gt;Fortunately, there is this amazing software called MetalLB &lt;a href="https://metallb.universe.tf/"&gt;2&lt;/a&gt;, designed for creating a load balancer on bare metal. Despite being in alpha stage (at the time of this writing) it works well and is enjoyed by folks in all types of cases, as evidenced by this GitHub "issue" &lt;a href="https://github.com/danderson/metallb/issues/5#"&gt;3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I installed it using the manifest option with zero modifications and used the Layer 2 config &lt;a href="https://metallb.universe.tf/configuration/#layer-2-configuration"&gt;4&lt;/a&gt;, with a subset of IP address from the default OpenVPN range of &lt;code&gt;10.8.0.0&lt;/code&gt;. The reason I used these IPs addresses is because I wanted to be able to access my "external" services from any machine in my cluster, including my master.&lt;/p&gt;

&lt;p&gt;I was originally planning to fiddle with a Ingress and get a site running, but the nginx ingress controller pod and the Apache on my node were not happy with each other so, in the interest of having success, I decided to start with the dashboard.&lt;/p&gt;

&lt;p&gt;It's a pretty basic task to create a LoadBalancer service for a single port &lt;a href="https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#configuration-file"&gt;5&lt;/a&gt;, so I'll share my manifest here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: load-balancer-dashboard
  name: dashboard-service
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  type: LoadBalancer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once I see what external IP my dashboard-server has obtained, I can go to the browser on the machine and visit &lt;code&gt;https://&amp;lt;external-ip&amp;gt;:8080/&lt;/code&gt; to access my dashboard. No more &lt;code&gt;kubectl proxy&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;P.S. I almost forgot. Make sure you comment out the &lt;code&gt;tolerations&lt;/code&gt; section of your dashboard manifest (or add them to your MetalLB manifest) so you can get the dashboard and metallb running on the same node. Ask if you give this a try and hit any issues!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>loadbalancer</category>
      <category>baremetal</category>
      <category>metallb</category>
    </item>
    <item>
      <title>Setting up Kubernetes on bare metal behind a NAT with OpenVPN</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Wed, 11 Sep 2019 00:46:39 +0000</pubDate>
      <link>https://dev.to/drazisil/setting-up-kubernetes-on-bare-metal-behind-a-nat-with-openvpn-5dj3</link>
      <guid>https://dev.to/drazisil/setting-up-kubernetes-on-bare-metal-behind-a-nat-with-openvpn-5dj3</guid>
      <description>&lt;p&gt;I've been wanting to setup a kubernetes (k8s) cluster for a while, mainly because I want to learn how it works. But, because I'm me, I refuse to do anything the easy way, so I didn't want to use GCP or AWS. I have 4 &lt;em&gt;bare metal&lt;/em&gt; machines floating about the internet, there is no reason I can't use them, right?&lt;/p&gt;

&lt;p&gt;Well, a couple reasons, actually. One, they aren't exactly bare metal, they are cloud bare metal, which means most of them are behind a weird NAT that doesn't share their external IP with them. So none of the interfaces have the external IP. Two, my home machine, which I plan to use for a control machine, is behind a router. So, again, NAT.&lt;/p&gt;

&lt;p&gt;Surely that's not a problem, right? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kubernetes imposes the following fundamental requirements on any networking implementation (barring any intentional network segmentation policies):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pods on a node can communicate with all pods on all nodes without NAT &lt;a href="https://kubernetes.io/docs/concepts/cluster-administration/networking/"&gt;1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Huh. Well, let's see. AWS and GCP clearly have to be able to make this happen with NAT, right? It's no way the IP space exists otherwise.&lt;/p&gt;

&lt;p&gt;Let's use a VPN. This post look perfect, an easy install script for OpenVPN &lt;a href="https://www.cyberciti.biz/faq/install-configure-openvpn-server-on-debian-9-linux/"&gt;2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installed it, connected the client, and the client promptly lost all internet connectivity. Huh. It could ping the VPN server, so that wasn't it.&lt;/p&gt;

&lt;p&gt;Turns out you will want to edit a couple lines from the server.conf.&lt;/p&gt;

&lt;p&gt;(you can find the full example here: &lt;a href="https://github.com/OpenVPN/openvpn/blob/master/sample/sample-config-files/server.conf"&gt;3&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;You want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remove the line that starts &lt;code&gt;push "redirect-gateway&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;add the &lt;code&gt;client-to-client&lt;/code&gt; line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the server can ping the client, and the client can ping the server. Success! &lt;/p&gt;

&lt;p&gt;There's just one thing left to do, and that's to tell &lt;code&gt;kubeadmin init&lt;/code&gt; to use the VPN. I used flannel as my pod network, so my init command was &lt;code&gt;kubeadm  -v 1 init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.8.0.1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And there we are!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;drazisil@central:~$ kubectl get nodes
NAME      STATUS   ROLES    AGE   VERSION
central   Ready    master   28m   v1.15.3
server1   Ready    &amp;lt;none&amp;gt;   26m   v1.15.3
server2   Ready    &amp;lt;none&amp;gt;   94s   v1.15.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>k8s</category>
      <category>kubernetes</category>
      <category>openvpn</category>
      <category>nat</category>
    </item>
    <item>
      <title>Creating a native Android app with Vue Native</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Sun, 07 Jul 2019 20:56:06 +0000</pubDate>
      <link>https://dev.to/drazisil/creating-a-native-android-app-with-vue-native-4ema</link>
      <guid>https://dev.to/drazisil/creating-a-native-android-app-with-vue-native-4ema</guid>
      <description>&lt;p&gt;Using &lt;a href="https://vue-native.io/"&gt;https://vue-native.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install &lt;code&gt;npm install -g react-native-cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install &lt;code&gt;npm install -g expo-cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install &lt;code&gt;npm install -g vue-native-cli&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g vue-native-cli
vue-native init &amp;lt;projectName&amp;gt; // Initializes crna project
vue-native init &amp;lt;projectName&amp;gt; --no-crna // Initializes react-native project
cd &amp;lt;project-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add or edit the android section of app.json&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#2-configure-appjson"&gt;https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#2-configure-appjson&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expo build:android&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;===========================================&lt;/p&gt;

&lt;p&gt;I'm sorry. This was going to be a more detailed post, but my mind's not in it. I promised a post, so here you go :(&lt;/p&gt;

</description>
      <category>vue</category>
      <category>android</category>
      <category>app</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Making a Panda (Polar bear) Entity in Minecraft Forge 1.12.x</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Wed, 01 May 2019 15:31:21 +0000</pubDate>
      <link>https://dev.to/drazisil/making-a-panda-polar-bear-entity-in-minecraft-forge-1-12-x-2m5p</link>
      <guid>https://dev.to/drazisil/making-a-panda-polar-bear-entity-in-minecraft-forge-1-12-x-2m5p</guid>
      <description>&lt;p&gt;Working Title: Giving form to a snow cube&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This tutorial was written around 1.12.2, and things may/have changed in 1.13. Being clear about the version here because I can't stand finding information that doesn't work and you have no clue why and it turns out things drastically changed. Ahem. I'm ok, let's carry on&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I like this seed &lt;code&gt;-8968754462810568592&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Want to make it clear from the (almost beginning) that I plan to copy Minecraft's native classes and modify what I need. It's saner that way.&lt;/p&gt;

&lt;p&gt;Right now we have a large white square that thinks it's a polar bear. Progress!&lt;/p&gt;

&lt;p&gt;Will document what I did after sleep when I know what I did. :D&lt;/p&gt;

&lt;p&gt;&lt;em&gt;insert gif of the sun coming up, rooster crowing, programming yawning and blinking, etc&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Morning! Ok, so where were we? Oh yes. Large white square that thinks it's a polar bear. Right. I know you want a picture, but let's start with some code!&lt;/p&gt;

&lt;p&gt;One thing I forgot last night was documenting how I added the entity. Since (for now) the panda is a clone of the polar bear, the Entity class is the same. The important part is how you register this class. That code is likely to change (it's already gone in 1.3.x), so here is the code, with comments and links&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Mod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EventBusSubscriber&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyForgeEventHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Register the EntityPanda class using the EntityEntryBuilder
     * Some details are here: https://github.com/MinecraftForge/MinecraftForge/pull/4408
     * The class is here: https://github.com/MinecraftForge/MinecraftForge/blob/1.12.x/src/main/java/net/minecraftforge/fml/common/registry/EntityEntryBuilder.java
     * It's already gone in 1.13.x
     * @param event
     */&lt;/span&gt;
    &lt;span class="nd"&gt;@SubscribeEvent&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;entityRegistration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RegistryEvent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Register&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;EntityEntry&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRegistry&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EntityEntryBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;entity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EntityPanda&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceLocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pandas"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"panda"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Panda"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;tracker&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;160&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;egg&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x4c3e30&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xf0f0f&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EnumCreatureType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AMBIENT&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ForgeRegistries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BIOMES&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValuesCollection&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Entries registered"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fdrazisil%2Fpandas%2Fblob%2Fmaster%2Fimages%2F2019-05-01_09.58.57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fdrazisil%2Fpandas%2Fblob%2Fmaster%2Fimages%2F2019-05-01_09.58.57.png" title="Not quite a polar bear" alt="large white square"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyway. It seems we need a model.&lt;/p&gt;

&lt;p&gt;This is going to be the &lt;code&gt;src/main/java/com/drazisil/pandas/model/ModelPanda.java&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Again, a clone of the ModelPolarBear class from Minecraft currently, so let's focus on the registration part.&lt;/p&gt;

&lt;p&gt;This code goes in your &lt;code&gt;preInit&lt;/code&gt; event handler (at least in 1.12). If you are using the proxy pattern (client/server/common (and there is no reason you shouldn't)) it will go in client side, since servers don't render anything, don't know how, and generally will throw fits if asked to. Since I'm not there yet, I'm doing a check to make sure this only runs client-side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSide&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Side&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CLIENT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"preInit: Client"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;RenderingRegistry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerEntityRenderingHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EntityPanda&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;RenderPanda:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fdrazisil%2Fpandas%2Fmaster%2Fimages%2F2019-05-01_10.11.42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fdrazisil%2Fpandas%2Fmaster%2Fimages%2F2019-05-01_10.11.42.png" title="well, it has the shape now..." alt="polar bear shaped entity with the black and purple checkered missing file texture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So close. Let's copy over the polar bear texture and call it panda.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/main/resources/assets/pandas/textures/entity/panda.png&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fdrazisil%2Fpandas%2Fmaster%2Fimages%2F2019-05-01_10.14.53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fdrazisil%2Fpandas%2Fmaster%2Fimages%2F2019-05-01_10.14.53.png" title="and we are back to a polar bear" alt="minecraft polar bear looking at the camera"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That looks like version 0.2.0 to me. In case anyone was wondering how I was spawning these, I'm going with the very high-tech method of giving myself a spawn egg for them when I break dirt. Which, I was going to skip, but it took some time to figure out so I'll cover it briefly&lt;/p&gt;

&lt;p&gt;This code goes in my event handler class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="cm"&gt;/**
     * Create an instance of a spawn egg, use
     * ItemMonsterPlacer.applyEntityIdToItemStack to appy the metadata of the
     * EntityPanda to it, and give it to the player on the EntityItemPickup event.
     * Make sure this only happens server-side
     *
     * @param event
     */&lt;/span&gt;
    &lt;span class="nd"&gt;@SubscribeEvent&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;pickupItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EntityItemPickupEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;EntityPlayer&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntityPlayer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntityPlayer&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEntityWorld&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isRemote&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;ItemStack&lt;/span&gt; &lt;span class="n"&gt;pandaEggStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ItemStack&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Items&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SPAWN_EGG&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;ResourceLocation&lt;/span&gt; &lt;span class="n"&gt;pandaResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceLocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pandas"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"panda"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pandaResource&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;ItemMonsterPlacer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;applyEntityIdToItemStack&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pandaEggStack&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pandaResource&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;inventory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addItemStackToInventory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pandaEggStack&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getItem&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" picked up by "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntityPlayer&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm doing a check here to make sure this only handles server-side, since you don't want to give items to players on the client or the server will never know. The &lt;code&gt;ItemMonsterPlacer.applyEntityIdToItemStack()&lt;/code&gt; is the interesting part here, this is what applies the panda as the "contents" of the spawn egg.&lt;/p&gt;

&lt;p&gt;Next steps are to give the panda a localized name and see about textures and behaviors. &lt;a href="https://minecraft.gamepedia.com/Panda" rel="noopener noreferrer"&gt;Pandas and Bamboo are coming in 1.14&lt;/a&gt;, but I picked up the Panda as part of the &lt;a href="https://www.minecraftshop.com/p/minecraft_mini_figure_chinese_mythology_series_blind_box.html" rel="noopener noreferrer"&gt;Minecraft Chinese Mythology Series 14 Mini-Figure Blind Box&lt;/a&gt; and really wanted to use it as an excuse to get modding again. Think of this as a backport, I guess?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was created as part of the README for my &lt;a href="https://github.com/drazisil/pandas#readme" rel="noopener noreferrer"&gt;Panda's mod&lt;/a&gt;. &lt;a href="https://dev.to/drazisil/setting-up-a-minecraft-mod-enviroment-in-vscode-it-s-easier-than-you-think-5bfc"&gt;Part 1&lt;/a&gt; discussed setting up a dev environment in VSCode. Thoughts and feedback welcome.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>minecraft</category>
      <category>entities</category>
      <category>12x</category>
    </item>
    <item>
      <title>Setting up a Minecraft mod environment in VSCode (It's easier than you think!)</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Wed, 01 May 2019 00:23:15 +0000</pubDate>
      <link>https://dev.to/drazisil/setting-up-a-minecraft-mod-enviroment-in-vscode-it-s-easier-than-you-think-5bfc</link>
      <guid>https://dev.to/drazisil/setting-up-a-minecraft-mod-enviroment-in-vscode-it-s-easier-than-you-think-5bfc</guid>
      <description>&lt;p&gt;Hi! This is my documented journey to create a Minecraft Forge mod. It's been a while since I created one, and I want to see if I still remember how things work.&lt;/p&gt;

&lt;p&gt;In addition, I'd like to try to do this using &lt;a href="https://code.visualstudio.com/"&gt;VSCode&lt;/a&gt;, instead of the usual IDEs recommended for this. Let's see how it goes!&lt;/p&gt;

&lt;p&gt;First, let's download Forge. The files can be found at &lt;a href="http://files.minecraftforge.net/_"&gt;http://files.minecraftforge.net/&lt;/a&gt;, and I think I want the MDK, but &lt;a href="https://mcforge.readthedocs.io/en/latest/gettingstarted/#from-zero-to-modding"&gt;let's see if the docs tell us&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Yep, the MDK. Ok, downloading the MDK for 1.12.2 - 14.23.5.2836...&lt;/p&gt;

&lt;p&gt;Oh, before we get too far along, I'm planning to track my progress with git commits and this readme. That way, if things get broken or strange, I can use git to backup, and you and I get a nice history we can look back on.&lt;/p&gt;

&lt;p&gt;Ok, the MDK is downloaded, let's unzip it.&lt;/p&gt;

&lt;p&gt;The docs say to only copy &lt;code&gt;build.gradle&lt;/code&gt;, &lt;code&gt;gradlew.bat&lt;/code&gt;, &lt;code&gt;gradlew&lt;/code&gt;, and the &lt;code&gt;gradle&lt;/code&gt; directory. I'll leave out &lt;code&gt;gradlew.bat&lt;/code&gt; since I'm developing on Linux.&lt;/p&gt;

&lt;p&gt;The next step is to run &lt;code&gt;gradlew setupDecompWorkspace&lt;/code&gt;. Since this is Linux, the correct command is &lt;code&gt;./gradlew setupDecompWorkspace&lt;/code&gt;, since the working directory isn't in the path.&lt;/p&gt;

&lt;p&gt;Ok, it looks like I don't have the java compiler (or JDK) installed on this computer. Your instructions to get a JDK installed for likely differ, so I'll leave this part out. DuckDuckGo is your friend.&lt;/p&gt;

&lt;p&gt;OpenJDK 8 installed and &lt;code&gt;./gradlew setupDecompWorkspace&lt;/code&gt; is successful.&lt;/p&gt;

&lt;p&gt;The two commands we want for testing are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;./gradlew runClient&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./gradlew runServer&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before we do that, we need a mod. Forge comes with a sample mod, but the instructions don't tell us to copy that. Let's do that though, so we have a starting place, and we can test this setup works&lt;/p&gt;

&lt;p&gt;Copied the &lt;code&gt;src&lt;/code&gt; directory from our unzipped MDK directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[19:59:27] [Client thread/INFO] [examplemod]: DIRT BLOCK &amp;gt;&amp;gt; minecraft:dirt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Great, it works! At this time, before we commit we probably want to create a `.gitignore and add a couple of things to it.&lt;/p&gt;

&lt;p&gt;Before I get too far into modding, I want to know that we can build our mod correctly as well. I'm going to to use &lt;a href="https://multimc.org/"&gt;MultiMC&lt;/a&gt; because it works all 3 major operating systems and makes creating Minecraft instances with the exact versions and mods you want so easy.&lt;/p&gt;

&lt;p&gt;Here goes &lt;code&gt;./gradlew build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[20:08:03] [Client thread/INFO] [examplemod]: DIRT BLOCK &amp;gt;&amp;gt; minecraft:dirt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Perfect! At this point, let's calls this version 0.1.0&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was created as part of the README for my &lt;a href="https://github.com/drazisil/pandas#readme"&gt;Panda's mod&lt;/a&gt;, but given my habit of not completing things I thought I'd share this part here in case it helped others. Thoughts and feedback welcome.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>minecraft</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Test splitting with Jest on CircleCI</title>
      <dc:creator>Molly Crendraven</dc:creator>
      <pubDate>Sun, 17 Mar 2019 19:34:32 +0000</pubDate>
      <link>https://dev.to/drazisil/test-splitting-with-jest-on-circleci-1i0c</link>
      <guid>https://dev.to/drazisil/test-splitting-with-jest-on-circleci-1i0c</guid>
      <description>&lt;p&gt;One of our customers asked on Twitter, "How do I setup test splitting on &lt;a href="https://circleci.com/"&gt;CircleCI&lt;/a&gt; with &lt;a href="https://jestjs.io/en/"&gt;Jest&lt;/a&gt;?"&lt;/p&gt;

&lt;p&gt;This is briefly explain in the &lt;a href="https://circleci.com/docs/2.0/parallelism-faster-jobs/#running-split-tests"&gt;CircleCI docs&lt;/a&gt;, but I can see where it could be confusing.&lt;/p&gt;

&lt;p&gt;I'm not the best writer, so I will let my code do the talking. This should serve as a good exercise in code documentation as well.&lt;/p&gt;

&lt;p&gt;A portion of my &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "scripts": {
    "test": "jest",
  },
  "jest": {
    "reporters": [
      "default",
      "jest-junit"
    ]
  },
  "jest-junit": {
    "outputDirectory": "test_results/junit"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My &lt;code&gt;.circleci/config.json&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: 2
jobs:
  build:
    parallelism: 3
    docker:
      # I want to make sure I know exactly what version I'm using
      - image: circleci/node:10.15.3

    working_directory: ~/repo

    steps:
      - checkout

      # Npm CI uses the package-lock.json file to ensure exact versions
      # This prevents changes and compromised upstream dependencies
      # from changing your project. It wipes the node_modules directory
      # so there is no need for a dependencies cache here.
      - run: npm ci

      # First we save the split test file names into an env
      # Then we pass that to jest
      - run:
          name: Run Jest tests using test splitting
          command: |
            TESTFILES=$(circleci tests glob "test/**/*.test.js" | circleci tests split --split-by=timings)
            npm test $TESTFILES

      - store_test_results:
          path: test_results

      - store_artifacts:
          path: test_results
          destination: test_results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope this helps!&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>jest</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
