Wyatt Winters has a website and here it is!https://wyattwinters.com/2022-03-29T00:00:00+00:00Lessons Learned from Shattering my Phone2022-03-29T00:00:00+00:002022-03-29T00:00:00+00:00Wyatt Winterstag:wyattwinters.com,2022-03-29:/lessons-learned-from-shattering-my-phone.html<p>I've had pretty good luck with mobile devices, all things considered. Having used them for the vast majority of my life, I've only broken them in a significant fashion a small handful of times. I've broken the digitizer (but not LCD panel) on a Nexus 7, I've had an iPhone …</p><p>I've had pretty good luck with mobile devices, all things considered. Having used them for the vast majority of my life, I've only broken them in a significant fashion a small handful of times. I've broken the digitizer (but not LCD panel) on a Nexus 7, I've had an iPhone 3GS get a serious battery bulge, but nothing ever too serious. I managed to recover my Nexus 7 by hooking a DualShock 3 up to it via USB-OTG. That was quite an adventure, but hey, it worked! </p>
<p>I also had my Gameboy Color get run over by my parents' minivan (my fault), but it was actually 100% fine aside from some cosmetic cracking and was fully functional. This was the same Gameboy I had dropped in the (unused) toilet previously. Nintendo has (had?) some solid hardware engineers, and I was quite a dumb kid.</p>
<p>Unfortunately, my Pixel 5a (3.5mm audio outputs will never die!) recently decided to slip from my grasp and fall in just the wrong way to land on a hard point and shatter both the screen and digitizer. No visual, no touch input. Truly a worst case scenario. I had backups, but I was not diligent in keeping them up to date and were a couple months old. I also had an older (non-broken) phone since I had upgraded semi-recently, so I was not phone-less for too long. </p>
<p>For fun and entertainment, let's go through some of my failed attempts to get data off the shattered device. These might have actually worked in different circumstances, but didn't for me:</p>
<ol>
<li>Attempt to use one of those USB-C to <em>everything</em> docks to get video out. Pixel 5a does not support video out over the USB-C port, and it's apparently a super uncommon feature in Android devices. How annoying.</li>
<li>Attempt to enable + trust ADB by hooking up a keyboard via USB-C and blind-navigating the menus with the assistance of an Android simulator. <ol>
<li>I'm <em>pretty sure</em> that I got ADB actually enabled via the keyboard method, but the tricky part is getting the "Trust this computer?" prompt to appear and still have keyboard input. I couldn't get both the keyboard input and my computer's connection to go at the same time, and the "Trust?" prompt disappears almost immediately after being disconnected from the computer. I couldn't manage to pit-crew the USB cables in and out fast enough.<ol>
<li>I tried to enable Bluetooth and use a Bluetooth keyboard I already had paired with my phone. For whatever reason (likely me failing to enable Bluetooth via blind keyboard inputs) I couldn't get the BT keyboard to pair. </li>
</ol>
</li>
</ol>
</li>
<li>Largely the same as above, but via blind touch. This was before I realized that the digitizer was 100% gone.</li>
</ol>
<p>My options exhausted, I bit the bullet and bought a new phone. With the replacement device in hand, I've learned some important lessons on operational diligence and the weird quirks of Android.</p>
<p>These tips are written with some assumptions already set:</p>
<ul>
<li>Your phone is Android based.</li>
<li>Your phone is rooted. Some of these tips may still apply to non-root users, but no promises.</li>
<li>This is based on Android 12. Future (or past) versions of Android may deviate.</li>
<li>You have the <a href="https://developer.android.com/studio/releases/platform-tools">Android Platform Tools</a> downloaded and installed.</li>
</ul>
<p>First and foremost, the Android Debugging Bridge is a <em>godsend</em> for so many reasons. ADB, as it's commonly known, is a USB (or network if you're feeling fancy) protocol for interfacing in all kinds of fun ways with an Android device. First and foremost, the <code>adb push</code> and <code>adb pull</code> commands are <em>significantly</em> easier than whatever MTP or other "automatic" file transfer malarkey Google decides is the latest default in Android this given week. There are also tools like <a href="https://github.com/Genymobile/scrcpy">scrcpy</a> which leverage ADB to provide a VNC-like interface to your phone from a computer running a major operating system. If you're on Android 12, make sure to compile it from source rather than using your distro-packaged version, it probably won't work.</p>
<p>The main issue with ADB is that since it provides great and powerful capabilities, Google tries very hard to make it difficult to use in what they declare to be an insecure fashion. I'm not here to make claims that the workflow I have isn't technically <em>less</em> secure than defaults, but I'm willing to accept the tradeoffs for "I can get data out of my phone if it breaks." </p>
<p>ADB operates similar to SSH, where a host computer will have an RSA keypair that must be trusted by the target device. (Yes, this is a gross simplification of SSH but let's run with it.) As of Android 12, by default, will pop a "Trust this computer?" prompt on the touch screen. That's all well and good, but not super helpful when the touch screen is all kinds of broken. Thankfully, there is a solution! In Settings -> System -> Developer Options (once enabled as described <a href="https://developer.android.com/studio/debug/dev-options">here</a>) there is a "Disable adb authorization timeout." This option will, as it says on the tin, disable the default trust revocation after 7 days for a trusted computer, even if the "always trust this machine" checkbox is enabled. With this toggle set, I plugged my replacement, non-shattered phone into my workstation and, with the "always trust" checkbox checked, trusted my computer.</p>
<p>After establishing this new (hopefully?) long-lived trust, I figured it would be prudent to backup the keys that are trusted. On Linux, those files will live in <code>~/.android/adbkey(.pub)</code>. I backed them up as attachments into my KeepassXC store, and have that squirreled away in various non-mobile backup solutions. This way, even if I'm at a separate computer, I can re-fetch those keys, install them, and my phone will trust them.</p>
<p>With the access portion of the equation more or less solved, the question comes down to how actual backups are done. <a href="https://www.titaniumtrack.com/titanium-backup.html">Titanium Backup</a> is, as far as I know, the gold standard for rooted Android backup and has been for a heck of a long time. It's a little strange on Android 12, and will sometimes require some fiddling to get apps and data to restore. I haven't run into any cases where backup files are completely unrestorable, but it can take some doing. On my new phone, I've set scheduled tasks to run <em>daily</em> with data and config changes. Titanium Backup supports straight-to-cloud uploads of your backups (and encryption) but I'm not a huge fan of trusting cloud storage with that raw data, and I haven't vetted the encryption too terribly much.</p>
<p>As a quick side note, <a href="https://signal.org/en/">Signal</a> does <em>not</em> play nicely with TitaniumBackup (and rightly so.) Signal does provide <a href="https://support.signal.org/hc/en-us/articles/360007059752-Backup-and-Restore-Messages">native backup support</a> which works a treat in my experience. I slap it into <code>/sdcard/TitaniumBackup</code> so I can pull it along with the Titanium Backup data files.</p>
<p>So, what to do with these backup packages once they exist on the phone storage? Google offers a tool called <a href="https://github.com/google/adb-sync">adb-sync</a> intended to have rsync-like behavior for ADB. However, I've been extremely pleased with SelfAdjointOperator's fork, the cleverly named <a href="https://github.com/SelfAdjointOperator/better-adb-sync">better-adb-sync</a>. I set up a quick and dirty Bash script to run a sync on both the <code>/sdcard/DCIM</code> folder (for photos) and the <code>/sdcard/TitaniumBackup</code> folder to pull my backup packages. Once on my local workstation, there are further backups and redundancy solutions in place, but that's perhaps out of scope for this writeup. </p>
<p>The final piece is to add an entry to my to-do list to remind myself <em>daily</em> to pull backups. Since the steps are "plug it in and run a script" I have very little excuse to not keep up to date on them. Next time I shatter my phone into a non-functional state, I will be far more prepared. Learning and growing! </p>
<p>In summary:</p>
<ol>
<li>Enable ADB, disable the "Disable adb authorization timeout" toggle, and leave it on!</li>
<li>Backup your computer's ADB RSA keypair!</li>
<li>Use Signal! Also, its native backup feature!</li>
<li>Get <a href="https://github.com/SelfAdjointOperator/better-adb-sync">better-adb-sync</a> for easy transfers to and from your device!</li>
<li>If at all possible, don't shatter your phone to begin with!</li>
</ol>Rubustat - the Raspberry Pi Thermostat2013-10-01T16:48:00+00:002013-10-01T16:48:00+00:00Wyatt Winterstag:wyattwinters.com,2013-10-01:/rubustat-the-raspberry-pi-thermostat.html<p>It's been some time since I actually wrote a blog post. Mostly because I have had nothing original to write, and partially because school keeps me busy. Let's change that!</p>
<p>I figured I would do a proper writeup on one of my summer projects - the Rubustat.</p>
<h2>Disclaimer</h2>
<p>While I enjoy …</p><p>It's been some time since I actually wrote a blog post. Mostly because I have had nothing original to write, and partially because school keeps me busy. Let's change that!</p>
<p>I figured I would do a proper writeup on one of my summer projects - the Rubustat.</p>
<h2>Disclaimer</h2>
<p>While I enjoy programming and enjoyed making this project immensely, I make no claims that I am good at programming. High level Pythoners may wish to look away. However, the only way to get better is practice, right?</p>
<h2>The inspiration</h2>
<p>While at home for the summer, the existing thermostat in the house was acting up. It wouldn't keep programmed settings, the display was a cheap LCD that was losing contrast, and it was generally an annoyance. Having ordered a couple Pis earlier in the summer (because why not, it's a $40 computer!), I quickly began researching the potential of a Raspberry Pi thermostat.</p>
<h4>Of course, someone already did it.</h4>
<p>As is typically the case on the internet, someone had already implemented my idea, and was selling products. <a href="http://makeatronics.blogspot.com">Nich Fugal</a> had done exactly what I planned - <a href="http://makeatronics.blogspot.com/2013/04/raspberry-pi-thermostat-hookups.html">hooked up an RPi to his thermostat</a>. Handily enough, he offers the schematics and parts list he used! He also makes and <a href="http://makeatronics.blogspot.com/2013/06/24v-ac-solid-state-relay-board.html">sells pre-made boards</a> for easy solder-and-go purposes!</p>
<p>However, I found his <a href="http://makeatronics.blogspot.com/2013/04/thermostat-software.html">software</a> implementation lacking, but admittedly functional.</p>
<h2>The project</h2>
<p><center>
<img alt="/images/rubustat/rubustathookups_regular.jpg" src="/images/thumbnails/rubustat/rubustathookups_regular.jpg"><br>
The controller board (left) and thermometer (right) crammed into the GPIO ribbon cable
<br>
I soldered the connector on the PCB backwards. Oops!
</center></p>
<p>While Nich did most of the hard work hardware wise, I knew I could improve the software. While I am by no means a web developer, I am halfway handy with Python, and Flask fulfilled my purposes well enough. Let's go through my amateur-at-best design process!</p>
<h3>The name</h3>
<p>Being a huge fan of lazy portmanteaus, I knew it had to be something raspberry related. The genus of the common raspberry is Rubus, so the name "Rubustat" practically made itself.</p>
<h3>The daemon</h3>
<p>The daemon was originally based on a straight copy of Nich's <a href="http://makeatronics.blogspot.com/2013/04/thermostat-software.html">software</a>. However, I found it to be a tad unstable, and used more external bash calls than I liked. While his use of outdoor temperature to determine heating vs cooling is clever, the primary user of the end product (my dad) preferred more manual control.</p>
<p>After some extended debugging, I found that it was difficult to cleanly kill off my daemon (which at this point was a endless while loop). I instead opted to use a daemon class written by <a href="http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/">Sander Marechal</a> which worked better. To fully stabilize/debug the daemon, I had to add stale PID checks.</p>
<p>In it's final version, the daemon handles the GPIO pins, sqlite logging (initially to make fancy graphs, but the thermometer I ended up using wasn't precise enough to make any graphs except ones that look like sawteeth), email error reporting (implemented because one of the alligator clips fell off on the temporary hardware and the house got outstandingly warm), and monitoring of the status file to know what temperature and mode to be in.</p>
<p>I also got to learn the word "hysteresis", so that's fun.</p>
<h3>The web UI</h3>
<p><center>
<img alt="/images/rubustat/phoneui_regular.png" src="/images/thumbnails/rubustat/phoneui_regular.png"> <br>
Firefox for Android on a Galaxy Note<br>
<br>
<img alt="/images/rubustat/desktopui_regular.png" src="/images/thumbnails/rubustat/desktopui_regular.png">
<br> Firefox on Windows
</center>
<br>
This is primary reason the project was created. We could get any number of cheap, difficult-to-control thermostats, or we could get any of a slightly smaller number of expensive, web-enabled thermostats. The beauty of this project is we got a cheap, web-enabled thermostat! You don't have to learn how to program the schedules! I doesn't even have the <strong><em>ability</em></strong> to run schedules! (feature forthcoming?)</p>
<p>The web UI looks like a hot pile of garbage. More importantly, however, is it a <strong>functional</strong> hot pile of garbage. I don't have much exciting to say about this interface. It writes directly to the status file, which is in turn read by the daemon and adjusts the GPIO pins accordingly.</p>
<p>The reason the interface is so dang big is because I have no idea how to do reactive design, and the idea was for the UI to be mobile-friendly. In a very inelegant way, it is mobile-friendly. I did however implement <a href="https://github.com/ftlabs/fastclick">fastclick</a> so it feels like you're poking a button rather than a Slowbro.</p>
<p>Another in the line of features inspired by catastrophic failure is the daemon status section. I felt rather silly when the web UI started without the daemon, so the adjustments made would have no effect. While playing with this functionality, I included the GPIO statuses above that, the colors corresponding to the LEDs on the physical board.</p>
<h3>The wrap up</h3>
<p>I took <em>no</em> security precautions in the code itself. If you make a Rubustat of your own <strong><em>DO NOT</em></strong> expose the RPi to the outside internet. It is a dreadful idea. It works just fine when confined to the LAN.</p>
<p>I'm actually pretty pleased with how this thing turned out. While it is by no means particularly pretty or elegant, it gets the job done, and doesn't catch fire. That's a success in my book.</p>
<p>If you want to look over the source or run it yourself, hit the <a href="https://github.com/wywin/Rubustat">Github repo</a>.</p>Backwards-compatible Short URL conversion of Mediawiki2013-07-14T14:27:00+00:002013-07-14T14:27:00+00:00Wyatt Winterstag:wyattwinters.com,2013-07-14:/backwards-compatible-short-url-conversion-of-mediawiki.html<p>Further adventures in mod_rewrite town! This time I had to convert a Mediawiki install to Short URLs while maintaining backwards compatability. Let's see how it went!</p>
<!-- more -->
<p>First, if you're like me, you don't plan ahead very much when doing software installs. A Mediawiki site I help with has been …</p><p>Further adventures in mod_rewrite town! This time I had to convert a Mediawiki install to Short URLs while maintaining backwards compatability. Let's see how it went!</p>
<!-- more -->
<p>First, if you're like me, you don't plan ahead very much when doing software installs. A Mediawiki site I help with has been running for some time, and several links exist pointing to old, ugly URLs like "www.example.com/wiki/index.php/Main_Page". However, the decision makers wanted the links to lose the "index.php" in the URL!</p>
<p>That's easy enough to do. The <a href="https://www.mediawiki.org/wiki/Manual:Short_URL">Mediawiki meta-wiki</a> has a great write up on the topic. They also link to <a href="http://shorturls.redwerks.org/">this handy wizard</a>, which I used.</p>
<p>You should come up with something like this:</p>
<div class="highlight"><pre><span></span><code>RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [QSA,L]
RewriteRule ^/?$ %{DOCUMENT_ROOT}/w/index.php [QSA,L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2 [L,QSA,B]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/?w/images/thumb/archive/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/w/thumb.php?f=$1&width=$2&archived=1 [L,QSA,B]
</code></pre></div>
<p>That's all great, but old links won't work anymore! Let's fix that by adding this before all the other new RewriteRules:</p>
<div class="highlight"><pre><span></span><code>RewriteRule ^/?wiki/index.php(/(.*))?$ /wiki/$2 [R=301,L]
</code></pre></div>
<p>Now you should have pretty URLs, and the old-style links should redirect to the new pretty ones too!</p>Serving identical content on HTTPS and Tor hidden service2013-07-03T21:52:00+00:002013-07-03T21:52:00+00:00Wyatt Winterstag:wyattwinters.com,2013-07-03:/serving-identical-content-on-https-and-tor-hidden-service.html<p>I recently came into an interesting problem- I wanted to serve the same website over the clearnet (the regular internet) using <em>only</em> HTTPS, and serve that same content over a Tor hidden service. I assume you have at this point a web server installed (I like Apache) that will successfully …</p><p>I recently came into an interesting problem- I wanted to serve the same website over the clearnet (the regular internet) using <em>only</em> HTTPS, and serve that same content over a Tor hidden service. I assume you have at this point a web server installed (I like Apache) that will successfully serve HTTPS exclusively, but need to add the Tor.</p>
<!-- more -->
<ol>
<li>
<p>Install Tor. You will want to use <a href="https://www.torproject.org/download/download-unix.html.en">the Tor Project's repos</a> to make sure you have the most up-to-date version.</p>
</li>
<li>
<p>Edit your torrc. It is likely at /etc/tor/torrc. Uncomment the following lines:</p>
<div class="highlight"><pre><span></span><code><span class="n">HiddenServiceDir</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">tor</span><span class="o">/</span><span class="n">hiddenService</span><span class="o">/</span><span class="w"></span>
<span class="n">HiddenServicePort</span><span class="w"> </span><span class="mi">80</span><span class="w"> </span><span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span><span class="p">:</span><span class="mi">80</span><span class="w"></span>
</code></pre></div>
<p>and/or adjust them accordingly. If you have Apache listening on 443 (for HTTPS) and 80, you should be set with this config.</p>
</li>
<li>
<p>Restart Tor to apply new settings. In Debian Wheezy: </p>
<div class="highlight"><pre><span></span><code>sudo /etc/init.d/tor restart
</code></pre></div>
</li>
<li>
<p>Get your hostname</p>
<div class="highlight"><pre><span></span><code><span class="n">sudo</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">tor</span><span class="o">/</span><span class="n">hiddenService</span><span class="o">/</span><span class="n">hostname</span><span class="w"></span>
</code></pre></div>
<p>should be a string of characters followed by ".onion".</p>
</li>
<li>
<p>Backup your private key</p>
<div class="highlight"><pre><span></span><code><span class="n">sudo</span><span class="w"> </span><span class="n">cp</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">tor</span><span class="o">/</span><span class="n">hiddenService</span><span class="o">/</span><span class="n">privateKey</span><span class="w"> </span><span class="o">/</span><span class="n">root</span><span class="w"></span>
</code></pre></div>
</li>
<li>
<p>Adjust your public html folder to move users based on their requested site</p>
<ol>
<li>
<p>Enable mod_rewrite (if not already)</p>
<div class="highlight"><pre><span></span><code>sudo a2enmod rewrite
</code></pre></div>
</li>
<li>
<p>Edit (on a default Debian Wheezy apache install) /var/www/.htaccess and add:</p>
<div class="highlight"><pre><span></span><code><span class="nv">RewriteEngine</span><span class="w"> </span><span class="nv">On</span><span class="w"></span>
<span class="nv">RewriteCond</span><span class="w"> </span><span class="nv">%</span><span class="p">{</span><span class="nv">HTTP_HOST</span><span class="p">}</span><span class="w"> </span><span class="o">!^</span><span class="nv">youronionaddress</span><span class="o">.</span><span class="nv">onion</span><span class="p">$</span><span class="w"></span>
<span class="nv">RewriteCond</span><span class="w"> </span><span class="nv">%</span><span class="p">{</span><span class="nv">HTTPS</span><span class="p">}</span><span class="w"> </span><span class="o">!</span><span class="nv">on</span><span class="w"></span>
<span class="nf">RewriteRule</span><span class="w"> </span><span class="p">(</span><span class="o">.*</span><span class="p">)</span><span class="w"> </span><span class="nv">https</span><span class="o">://</span><span class="nv">%</span><span class="p">{</span><span class="nv">HTTP_HOST</span><span class="p">}</span><span class="nv">%</span><span class="p">{</span><span class="nv">REQUEST_URI</span><span class="p">}</span><span class="w"></span>
</code></pre></div>
</li>
</ol>
</li>
<li>
<p>Test it out!</p>
</li>
</ol>
<p>The .htaccess does the following:</p>
<ol>
<li>
<p>Is the user not requesting the .onion? (Tor hidden services get confused when you talk HTTPS to them)</p>
</li>
<li>
<p>Is HTTPS not on? (If they don't want the .onion, and HTTPS isn't on, we should turn it on!)</p>
</li>
<li>
<p>If conditions 1 and 2 are met:</p>
</li>
<li>
<p>Send them back to whatever address they requested, but with HTTPS.</p>
</li>
</ol>
<p>Granted this does NOT hide the location of your webserver, but it will allow Tor users to save precious exit node bandwidth by staying inside the Tor network. This is especially neat because changes made on the clearnet will be reflected on the hidden service side, and vice versa. </p>Dota 2 on Xubuntu 13.042013-06-20T00:50:00+00:002013-06-20T00:50:00+00:00Wyatt Winterstag:wyattwinters.com,2013-06-20:/dota-2-on-xubuntu-1304.html<p><strong><em>UPDATE</em></strong> Valve was awesome enough to do a native Linux port. <a href="http://store.steampowered.com/app/570/">Get that version instead!</a></p>
<p>Dota 2 is a really good game. Linux is really good. Out of the box, they don't play nice together. Let's fix that!</p>
<!-- more -->
<p>First, let's lay out the details.</p>
<p>I am running </p>
<ul>
<li>Xubuntu 13.04 …</li></ul><p><strong><em>UPDATE</em></strong> Valve was awesome enough to do a native Linux port. <a href="http://store.steampowered.com/app/570/">Get that version instead!</a></p>
<p>Dota 2 is a really good game. Linux is really good. Out of the box, they don't play nice together. Let's fix that!</p>
<!-- more -->
<p>First, let's lay out the details.</p>
<p>I am running </p>
<ul>
<li>Xubuntu 13.04 Raring Ringtail</li>
<li>AMD Phenom(tm) II X4 970 Processor</li>
<li>Nvidia GTX 465 with 319.23 drivers</li>
<li>wine-1.6-rc2</li>
</ul>
<p>and on all low settings I can easily get a solid 60 FPS in-game, with no dips. Your mileage may vary according to your hardware. </p>
<h2>Drivers</h2>
<p>First, we need the latest drivers from Nvidia (or ATI, depending on your card). The open source drivers are fine for day-to-day computing, but they don't handle games so well. A rather sexy fellow named Harold Hope made a delightful and very colorful script called <a href="http://smxi.org/site/donations.htm">sgfxi</a> that makes installing your latest and greatest binary drivers very easy. Grab a root shell, and run</p>
<div class="highlight"><pre><span></span><code>cd /usr/local/bin && wget -Nc smxi.org/sgfxi && chmod +x sgfxi
</code></pre></div>
<p>Now we need to get into a non-X shell. CTRL-ALT-F1 will do the job nicely. Log in, and run</p>
<div class="highlight"><pre><span></span><code>sudo sgfxi
</code></pre></div>
<p>and follow the wizard. You may have to do this once or twice, to remove the old free-as-in-speech drivers before installing the binary drivers. It should be easy to follow.</p>
<h2>Getting Wine</h2>
<p>Man, Wine has improved <em>so much</em> since I last messed with it around the Gutsy Gibon days. Let's add their PPA</p>
<div class="highlight"><pre><span></span><code>sudo add-apt-repository ppa:ubuntu-wine/ppa && sudo apt-get update && sudo apt-get install wine winetricks
</code></pre></div>
<p>and wait for all the goodies to download.</p>
<p>After Wine is installed and situated, we will follow a modified/updated version of the writeup on <a href="http://appdb.winehq.org/objectManager.php?sClass=version&iId=24458">WineHQ</a>. </p>
<p>Here's what we need to do:</p>
<div class="highlight"><pre><span></span><code>WINEPREFIX=~/.wine_dota2/ winecfg
</code></pre></div>
<p>will set up a new bottle (haha wine puns) to be our Dota 2 machine. </p>
<h2>Getting Steamy</h2>
<p>Now, let's install Steam!</p>
<div class="highlight"><pre><span></span><code>wget http://winetricks.org/winetricks
WINEPREFIX=~/.wine_dota2/ sh winetricks --no-isolate steam
</code></pre></div>
<p>Follow the wizard, let it update, and log into Steam. Download Dota 2, and add some launch options. Right click Dota 2 in the games list -> properties -> set launch options. These work for me:</p>
<div class="highlight"><pre><span></span><code>-novid -console -noforcemaccel -forcemspd -useforcedmparms -high -nod3d9ex -nod3dx -noborder -gl
</code></pre></div>
<p>"-novid" disables the intro video. "-console" enables the console. "-noforcemaccel -forcemspd -useforcedmparms" disables mouse acceleration. "-high" starts the game with high CPU priority. "-nod3d9ex -nod3dx -gl" are video tweaks to make it run smoother. "-noborder" starts the game in a borderless window, making alt-tabbing out should the need occur much easier. </p>
<p>It should be noted that with Wine wine-1.6-rc2 and the setup outlined above, I am not affected by any of the bugs on the <a href="http://appdb.winehq.org/objectManager.php?sClass=version&iId=24458">WineHQ page</a>. I'm not sure if that's luck of my hardware or improvements in Wine. There is some hitching when the game is loading things (hero selection, playing new sounds for the first time) but once everything is loaded up, the hitching disappears. Very playable, and not booting into Windows anytime soon!</p>
<p>I don't have comments on this blog because comments are for jerks and weirdos. Email me if you have questions or comments, and I will edit the post accordingly. glhf!</p>