<!-- navigation bar -->
<nav class="nav-bar">
- <ul>
- <li><a href="https://dpolakovic.space">About</a></li>
- <li><a href="https://dpolakovic.space/blog.php">Blog</a></li>
- <li><a href="https://dpolakovic.space/dir.php">Web directory</a></li>
- <li><a href="https://dpolakovic.space/mars-clock.php">Mars clock</a></li>
- <li><a href="https://www.dpolakovic.space/dead-drop.php">Dead drop</a></li>
- <li><?php serverStatus() ?></li>
- </ul>
+ <ul>
+ <li><a href="https://www.dpolakovic.space">About</a></li>
+ <li><a href="https://www.dpolakovic.space/blog.php">Blog</a></li>
+ <li><a href="https://www.dpolakovic.space/dir.php">Web directory</a></li>
+ <li class="dropdown">
+ <input type="checkbox" id="dropdown-toggle">
+ <label for="dropdown-toggle">Other stuff</label>
+ <ul class="dropdown-content">
+ <li><a href="https://www.dpolakovic.space/mars-clock.php">Mars clock</a></li>
+ <li><a href="https://www.dpolakovic.space/dead-drop.php">Dead drop</a></li>
+ </ul>
+ </li>
+ <li><?php serverStatus() ?></li>
+ </ul>
</nav>
<!-- page content -->
- a collaborative catalog of free software<br>
<a href="https://winworldpc.com/home">WinWorld</a>
- online museum/library of vintage operating systems<br>
- <a href="https://eblong.com/infocom/">Infocom catalog</a>
+ <a href="https://eblong.com/infocom/">Infocom catalog</a>
- every Infocom text adventure ever<br>
- <a href="https://kolibrios.org/en/">KolibriOS</a>
- - operating system on 1,44MB floppy<br>
- <a href="https://atariage.com/index.php">AtariAge</a>
- - hub for enthusiasts of Atari PCs and consoles<br>
+ <a href="https://consolemods.org/wiki/Main_Page">Console mods wiki</a>
+ - hub for hacking old gaming consoles<br>
+ <a href="https://tiplanet.org/forum/portal.php">TIplanet.org</a>
+ - Texas Instruments calculators hacking community<br>
</p>
<p>
<b>programming</b><br>
- it does, exactly what it says [3]<br>
<a href="https://wine.htmlvalidator.com/">Installing Wine on Linux</a>
- this is tricky task for many distros<br>
+ <a href="https://www.av8n.com/physics/thermo/">Av8ns thermodynamics</a>
+ - great thermodynamics reference page<br>
+ <a href="https://www.swpc.noaa.gov/">SWPC NOAA</a>
+ - space weather forecast [3]<br>
+ <a href="https://repair.wiki/w/Main_Page">Repair wiki</a>
+ - guides and sheets for HW repairs<br>
</p>
<p>
<b>other</b><br>
<a href="https://lkml.iu.edu/hypermail/linux/kernel/">Linux Kernel Mailing List</a>
- this is my preferred instance<br>
+ <a href="https://brisray.com/web/webring-list.htm">Webring list</a>
+ - pick a community and meet fellow netizens<br>
<a href="https://wiki.eth0.nl/index.php/LackRack">Lack rack</a>
- nice hack that I use for my servers<br>
- <a href="https://www.floppydisk.com">Floppydisk.com</a>
- - new and refurbished floppies for okay prices [3]<br>
- <a href="https://brisray.com/web/webring-list.htm">Webring list</a>
- - pick a community and meet fellow netizens<br>
- <a href="https://www.gutenberg.org/">Project Gutenberg</a>
+ <a href="https://www.gutenberg.org/">Project Gutenberg</a>
- my go to place to get books online<br>
- <a href="https://www.av8n.com/physics/thermo/">Av8ns thermodynamics</a>
- - thermodynamics reference page<br>
- <a href="https://www.swpc.noaa.gov/">SWPC NOAA</a>
- - space weather forecast [3]<br>
+ <a href="https://www.floppydisk.com">Floppydisk.com</a>
+ - new and refurbished floppies for okay prices [3]<br>
+ <a href="https://www.starringthecomputer.com/">Starring the computer</a>
+ - all computers from silver screen<br>
+ <a href="https://www.retrojunk.com/">Retrojunk.com</a>
+ - center of old, forgotten and some lost media<br>
<a href="https://en.uesp.net/wiki/Morrowind:Morrowind#Quest_Information">UESP wiki</a>
- - everything I ever needed for Morrowind [1, 3]
+ - everything I ever needed for Morrowind [1, 3]<br>
+ <a href="https://www.starwarstimeline.net/Complete%20Saga.htm">STARWARStimeline.net</a>
+ - your real life holocron<br>
+
</p>
<br>
<hr>
Publications on this domain are licensed under
<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>.
<br>
- This site uses client side scripting. Please, read the source code
+ <a href="https://www.dpolakovic.space/blogs/javascript">This site uses client-side scripting.</a>
+ Please, read the source code
<a href="https://git.dpolakovic.space/?p=my-website;a=tree">here</a> for more information.
</footer>
<br><br>
}
}
+function serverStatusRo() {
+ $websiteUrl = "https://git.dpolakovic.space";
+
+ if (isWebsiteOnline($websiteUrl)) {
+ echo '<a class="gitserver" href="https://git.dpolakovic.space">Git ramibaf | ifdeba </a>';
+ } else {
+ echo '<a class="gitserver" href="">Git ramibaf | ofdeba</a>';
+ }
+}
+
// Function for index.php to generate random second sentence
function randomSentence() {
$file = "./php/rnd.txt";
// Function to convert RSS file into blog page
function printBlog2($rss_file) {
-
- // Load the XML file
- $xml = simplexml_load_file($rss_file);
-
- // Check if the XML is loaded successfully
- if ($xml !== false) {
- // Loop through each <item> tag in the RSS feed
- foreach ($xml->channel->item as $item) {
- $title = (string) $item->title;
- $link = (string) $item->link;
- $description = (string) $item->description;
- $pubDate = (string) $item->pubDate;
- $image_url = (string) $item->image;
- $pos = (string) $item->pos;
-
- // Output
- echo "<div class=\"blog-prev\">" .
- "<div class=\"blog-prev-img\">" .
- "<a href=\"$link\">" .
- "<img src=\"$image_url\" alt=\"Blog picture\"".
- "style=\"object-position: $pos ;\">" .
- "</a></div>";
- echo "<div class=\"blog-prev-text\">".
- "<a href=\"$link\">$title</a><br>";
- echo substr($pubDate, 5, 12) . "<br>";
- echo "<i>$description</i></div></div><br>";
- }
+ // Load the XML file with namespace handling
+ $xml = simplexml_load_file($rss_file, 'SimpleXMLElement', LIBXML_NOCDATA);
+ // Check if the XML is loaded successfully
+ if ($xml !== false) {
+ // Loop through each <item> tag in the RSS feed
+ foreach ($xml->channel->item as $item) {
+ $title = (string) $item->title;
+ $link = (string) $item->link;
+ $description = (string) $item->description;
+ $pubDate = (string) $item->pubDate;
+ $image_url = (string) $item->image;
+ $pos = (string) $item->pos;
+
+ // Output
+ echo "<div class=\"blog-prev\">" .
+ "<div class=\"blog-prev-img\">" .
+ "<a href=\"$link\">" .
+ "<img src=\"$image_url\" alt=\"Blog picture\"".
+ " style=\"object-position: $pos ;\">" .
+ "</a></div>";
+ echo "<div class=\"blog-prev-text\">".
+ "<a href=\"$link\">$title</a><br>";
+ echo substr($pubDate, 5, 12) . "<br>";
+ echo "<i>$description</i></div></div><br>";
+ }
} else {
- // If the XML file fails to load
- echo "Failed to load the blogs. The rss.xml file is either missing or corrupted.";
- }
+ // If the XML file fails to load
+ echo "Failed to load the blogs. The rss.xml file is either missing or corrupted.";
+ }
}
// Function to print my books on the website
<?xml version="1.0" encoding="UTF-8"?>
-<rss version="2.0">
- <channel>
- <title>dpolakovic.space</title>
- <link>https://www.dpolakovic.space</link>
- <description>Some obscure thoughts caught on the Web.</description>
- <language>en-us</language>
+<rss version="2.0"
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
+ xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
+<channel>
+<title>dpolakovic.space</title>
+<link>https://www.dpolakovic.space</link>
+<description>Some obscure thoughts caught on the Web.</description>
+<language>en-us</language>
+<lastBuildDate>Wed, 26 Mar 2025 15:00:00 GMT</lastBuildDate>
+<sy:updatePeriod>daily</sy:updatePeriod>
+<sy:updateFrequency>1</sy:updateFrequency>
- <item>
- <title>This site uses client-side scripting</title>
- <link>https://www.dpolakovic.space/blogs/javascript.html</link>
- <description>Spooky, scary JavaScript update.</description>
- <pubDate>Thu, 5 Jun 2025 22:00:00 GMT</pubDate>
- <image>https://www.dpolakovic.space/blogs/pics/jst.jpg</image>
- <pos>100% 1</pos>
- </item>
-
- <item>
+ <item>
<title>Stormtrooper's guide to Galaxies</title>
<link>https://www.dpolakovic.space/blogs/star-wars-galaxies</link>
<description>"You seen that new VT-16?"</description>
<pubDate>Wed, 26 Mar 2025 15:00:00 GMT</pubDate>
+ <author>David Polakovic</author>
<image>https://www.dpolakovic.space/blogs/pics/sw5.jpg</image>
<pos>100% 1</pos>
+ <content:encoded><![CDATA[
+ <p> I just love autumn, or fall for my single north-American reader. It's colorful yet menacing, beautiful yet scary. And even though the Halloween is not celebrated in my part of the planet, I like to read thrillers and horrors during this part of the year, especially during the September. November however, belongs good old STAR WARS books and this year I combined my early and late autumn reading together. </p> <p> I remember it like yesterday when the daring Death Troopers was the newest entry in the STAR WARS library. Since 2009 I haven’t found time to read it, until last year and upon finishing the last page I saw once again the illness of cheap sci-fi shlocks – the advertisement. </p> <p> <em>The Death Troopers infection continues in STAR WARS Galaxies[*].<br> Where the movies ends, your STAR WARS adventure begin! </em> </p> <p> Is it finally time, to try this game which just like the troopers, lives after its death? Why not, I always wanted to roleplay a Stormtrooper - the faceless hero of the Empire. There are many versions of the game, but I went with the OG version - the SWGemu. It has the best documentation and except for the client side, the game is completely free software (AGPLv3). You can check the source for the Launcher, Engine3, Core3 and tools on their own <a href="https://git.swgemu.com/swgemu/">Git instance</a>. </p> <p> Their <a href="https://www.swgemu.com/forums/content.php?r=179-Install-SWGEmu">installation manual</a> is well written and quite precise, but there are few extra steps for running the game on GNU\Linux. Simply <a href="https://www.myabandonware.com/game/star-wars-galaxies-an-empire-divided-be9">obtain the game</a> and install it via Lutris. Then follow the guide to Step 3, but download the Windows version of the launcher. Open the Lutris and in library, right click on the newly installed <em>STAR WARS Galaxies</em> and pick <em>configure</em> > <em>game options</em> and change the <em>executable</em> path to your launcher location. Save the configuration and run the game. Then follow the rest of the guide. </p> <p> After much smoother installation than expected, I created the account. Luckily my <em>handle</em> was free, but the registration is hand reviewed, and it seems that nobody is in hurry to validate my non-synthetic heritage. So I spend next few days by reloading my mailbox and hastily reading the <a href="https://www.swgemu.com/archive/scrapbookv51/data/20070128130746/manual_printview_001.html">game manual</a>[**]. As soon as my account was activated, I fired up my endless Rush playlist and jumped into character creation. </p> <ul> <strong>server:</strong> Finalizer (SWGemu default)<br> <strong>profession:</strong> marksman<br> <strong>race:</strong> human<br> </ul> <p> And so I arrived in Bestine, capital of Tatooine around 1 ABY. “Hello, anybody here?” I asked in the planetary chat with no response, even when the server population reached 180 people. I saw a few new messages in my inbox, one being from the Imperial Navy. They asked me to join the ranks of Stormtroopers as the ever present threat of the Rebels, assassins, smugglers and other scum looms over the Empire. I wasted no time and found an Imperial recruiter <em>Protacke Daxevi</em> near town square, who told me right away that my faction score is too low and I should do some quests for the Empire as freelancer first. There is this Imperial garrison next to the town, which looks like good place to start. </p> <p> A terminal gave me quest to go kill some random rebels in desert and destroy their hologram replication machine. I equipped my rusty <em>CDEF carbine</em> and went north of the Bestine to deal with this Rebel scum. As I approach the location from south, I see few Wookies in distance. So I lay down to take good shot from distance, when suddenly… I am attacked by wild Bantha and in few hits I am dead. So I contact my local clone dealership to see what are my options and my guy tells me that my new body can be ready to go in few seconds back in Bestine with little fee of item condition drop and lowered health. So I try again, this time from hills on the east. But as soon as come to the location and crouch to get better view I am killed by pack of Scyks. Bestine cloning lab it is – stats lowered again. </p> <p> Let's regroup. I went to local bazaar to get some better weapon. I bought <em>DH17</em> carbin which cost me my life savings. Then I got a message from seller, that I should come a get the gun in person in Mos Eisley. So I spawned my landspeeder, created waypoint and off I went. After getting the weapon, I stopped in <em>the local cantina</em> to get healing and buffs from performers there. Next step: Kill some space pests to gain skill and confidence with the weapon. This went smooth, but I was unable to level up my skills because that costs money which I don't have. Time to pick some quest in local terminal. </p> <p> "Exterminate wildlife for the Empire" sounds like something I am up to. The Rebels samizdat will have to wait for now, because the Emperor demands clean roads. I accept the quest and immediately atempt to spawn my landspeeder to get to the location. No landspeeder in my inventory. It seems it was one use only. I tighten my shoe ties and on foot I go. After a long while I entered the insect hive that threatens fellow citizens of the Empire. Obliterated in few shots, easy. But since the quest was taken from a "terminal" and not an "Imperial terminal", I got no imperial faction points. But 2k credits is nice too. It's time to deal with the Wookies. </p> <p> While in the desert, traversing the terrain without a landspeeder is super boring, so I stop in closest settlement to look for any fast travel option available. I am unable to buy any vehicle, but there is a spaceport. 100 bucks for "instant" teleport is the beast deal ever. Instant is in quotes, because I had to wait 4 minutes for next shuttle to arrive. Upon arriving to the Bestine again, I went directly to the Rebel hideout. Approached slowly, aimed and dealt with Wookies one by one. Base exploded and 3000 credits arrived to my bank account directly from the Emperor, earning 10 Imperial points too. Not much, but it's a good start. </p> <p> With better items it took me 5 missions to get over the 200 Palpatine points. Some missions are harder than other, but they all boil down to destroying rebel infrastructure somewhere in the desert. During this loop I even found out how to recall my landspeeder! (Ctrl + D) And for last two missions I got help from only living person who was active in the planetary chat. Bounty hunter who agreed to help aspiring Stormtrooper in his spare time. He even showed me his city on Naboo, where he is building a giant R2. </p> <p> After proving my loyalty, <em>Ms. Daxevi</em> was more than happy to welcome me in the Empire forces. I asked for the sweet armor and she offered me all pieces for okay prices. But I soon realized that the prices were not in credits, but rather in the stupid faction points, with prices varying from 2k for the helmet to over 5k for the chest piece. Full armor costs almost 20k points. If 5 missions can get you ~200 points, it will take me about 100 missions to afford the full set. </p> <em> And thats where the grind starts... </em> <p> So I hit up my bounty hunter friend who is way experienced than me and asked him if he wants to help the Empire to put this place to the order. Luckily, he had nothing better to do. We finished couple of high level <em>Destroy</em> missions, but this wasn't effective. Firstly, all XP and FP from NPC kill goes to player who does the most damage - no last hit policy. Only the mission reward (money and FP) are split between grouped players. (<a href="https://git.swgemu.com/swgemu/Core3/src/branch/unstable/MMOCoreORB/src/server/zone/managers/creature/CreatureManagerImplementation.cpp">CreatureManagerImplementation.cpp</a> line 668) </p> <p> Also, the <em>awardFactionStanding</em> function from <a href="https://git.swgemu.com/swgemu/Core3/src/branch/unstable/MMOCoreORB/src/server/zone/managers/faction/FactionManager.cpp"> FactionManager.cpp </a> line 90 stands: void FactionManager::awardFactionStanding(CreatureObject* player, const String& factionName, int level) {<br> ...<br><br> float gain = level * faction.getAdjustFactor();<br> float lose = gain * 2;<br> bool gcw = false;<br> ...<br></p> <p> Where the <em>adjustFactor</em> is read from <a href="https://git.swgemu.com/swgemu/Core3/src/branch/unstable/MMOCoreORB/bin/scripts/managers/faction_manager.lua">faction_manager.lua</a> and is set to 1 for almost all creatures. Which means the NPC levels (and the amount of FP you get for killing them) is static and only modifier for spawning higher level enemies is your weapon skills (Ctrl + C, middle section on left) which determines the mission difficulty in the terminal. Consider too, that while playing solo <em>destroy missions</em> you can be rewarded as much as 6000 credits and 200 faction points pretty soon while grinding. When in group, I was unable to spawn mission with reward higher than 12000 credits and 250 faction points, which again are split. With group of 10 players, you get even less then alone. </p> <p> So, the optimal way to play these missions is to solo, buff and refresh the mission until you get around 6K credits reward. Accept the mission and refresh the terminal again until the second mission has the same direction as the first one and your reward is at least 5K. Spawn the swoop, finish missions, repeat. This way, you can do two missions in ~10 minutes giving you 10k credits and 500 faction points (including FPs for NPC kills too). If you are lucky, you can get random rebel base spawn on the way there/back which can give you 100-200 more points. </p> <p> In order to optimize the mission time it's important to invest in good weapon. There are only two important factors to look at: <em>max dmg</em> and <em>speed</em> everything over 300 max dmg and 1.0 speed is considered good weapon, at least for carbine - the jack of all trades. It is okay to look for such toys over bazaar, but make sure to check the player vendors too in most right bazaar tab. These are more expensive, but you get what you pay for. However, the best way to get good laser stick is to visit <em>the cantina</em> on Tatooine and order one directly from weapon smith player. There is always someone more than happy to help you. I got mine E11 carbine from Jeres. </p> <p> Many players will say that more efficient way how to farm FPs is to kill Rebel NPCs on places where they spawn in high numbers like Rori Starport or Naboo weapons facility. I had to disagree. When starting as new player, you can easily get swarmed by them and they will drop 100 credits and 20 FP each. Until you manage to get some strong weapon which can cut trough them fast, it's not worth the hassle. Then again, for that weapon you need a lot of money... </p> <p> <em>Quickly about the recon missions</em>. They can be accessed via the same terminal and the goal is to go to some place in desert, stay there, and return. Sharp readers can spot a loop, however implementing it is impossible. There is no command that would auto-walk player to a target. You can partially overcome this with a droid and /patrol and /follow command, but still, you can't target the mission waypoint nor access the mission terminal with commands. Then there is the speeder condition. The <a href="https://git.swgemu.com/swgemu/Core3/src/branch/unstable/MMOCoreORB/bin/scripts/object/mobile/vehicle">Swoop</a> will last ~7 hours and even 7 hour Recon shift might not always cover the repairs. </p> <p> I stuck to the <em>destroy missions</em> and by the time I bought half of the armor, I was drowning in credits so I wanted to "buy the influence". Every player can give you his faction points with /delegate command. Smugglers can even directly buy FPs from faction recruiters. You can offer to buy these points from other players, but expect it will be costly. Best place to do so is again... <em>the cantina</em>. So after grinding for everything except for torso, helmet and shoulder pads, I went to the Mos Eisley to buy me the missing parts. When I finally got the armor, went to insure it in closest cloning facility so it will deteriorate slower. </p> <p> With my new shiny armor I went sight seeing. You can visit the escape module in which R2 and 3PO fell on Tatooine, Jabbas palace with my boi Boba, Ewok tree villages and even (now) abandoned Rebel base on Yavin IV. In Jabbas palace, there was the original Max Rebo band, not the special edition one. On Endor, I wasn't able to find any bunker resembling the location from the Return of the Jedi. Maybe it wasn't built yet? I also went to see the old Mos Espa pod racing track from my favorite episode and even raced one circle on it. Since it was soon after the server rebooted I got track record and placed first in leaderboard. (I bet you can't beat mine 504,56 seconds) But you can visit many more. These points of interests are all marked in you map by default. If you want to meet "the management" you can check these coordinates on Naboo: </p> <p> Speaking of which, there are some good story oriented missions too. I can recommend visiting Lt. Harburik in Mos Eisley. He has some problem with a Stormtrooper who wants to paint his armor lavender. Sgt. Tokai and her colleagues are dealing with Death Star rubble that fell on on Yavin IV - that was nice. But the best mission set you can get is from Lt. Sabol near Bestine starport on Tatooine. Other than that you can experiment with some non-combat skills. I wanted to start an Imperial metal band <em>Durasteellica</em>. Even though I managed to get some droids to do me background I gave up because the <em>xantha</em> instrument wasn't presnet in SWGemu. It was added after the dreaded Combat Update. Also I wasn't able to convince Darth Vader to join our band coz he wouldn't perform <em>Enter the sandplanet</em>. Our <em>nalargon</em> R2 unit had issues with <em>Master of droids</em>. And to be honest <em>Ride the Force lightning</em> and <em>Fade to Dark side</em> weren't popular either. </p> <p> Here are some key takeaways from my winter sessions: <ul> <li>Use "/chatr join genchat" to join only living chat</li> <li>Early on, kill vermin around towns for easy XP.</li> <li>Go meet people in cantinas.</li> <li>Take medic and musician buffs. Pay for them with /tip if you can.</li> <li>Rank up so you can hold more faction points.</li> <li>Buy Swoop, not Speeder bike. And always have 2 so you won't get stuck.</li> <li>Get your self weapon with speed 1.0 or lower and max dam 300 or more. And remember...</li><br> ...becoming a Stormtrooper is hard. Don't make fun of them for bad aim.<br><br><br> </ul> </p> <p> SWGemu is free software project run by community for 20 years now. If you want to help them pay bills for the server, consider <a href="https://www.swgemu.com/forums/awcoding.php?do=payment&sid=ds">throwing some money</a> their way. For time well spent, I sure did. </p> <p><img src="./pics/sw5.jpg" alt="a generic star wars picture"></p> <br> <hr> <em> <p> * The title of the game is super messed up. STAR WARS story is all happening in one single galaxy. There is only one alien race that came from another galaxy, but even then, the story follows their deeds in the original galaxy, not their home one. This reminds me the mistake or confusion in the end of Empire strikes back, where Luke and Leia are looking from the spaceships window on something that resembles galaxy, which would imply, that they left the original galaxy to hide from The Empire. This, however, was not possible for various reasons. Later, they addressed this saying that they were looking at a "galaxy-like nebula". STAR WARS was always a mess. </p> <p> ** The manual is comprehensive, but for some reason the navigation links don't work. I manually edited the last three numbers at the end of the URL in order to navigate the manual. E.g. 155 is controls page, 035 explains class mechanics and page 053 explains how the combat works. </p> </em> <br>
+ ]]></content:encoded>
</item>
<item>
<link>https://www.dpolakovic.space/blogs/phantom-menace</link>
<description>An inevitable STAR WARS rant.</description>
<pubDate>Sun, 18 Aug 2024 17:00:00 GMT</pubDate>
+ <author>David Polakovic</author>
<image>https://www.dpolakovic.space/blogs/pics/starwars26.jpg</image>
<pos>100% 1</pos>
- </item>
+ <content:encoded><![CDATA[
+ <img src="./pics/starwars26.jpg" alt="TITLE"> <p> The year is 1999. A new STAR WARS movie is about to hit theaters, and fans still have a sour taste in their mouths from the special editions released two years prior. However, the Extended Universe is flourishing, thanks to the well-orchestrated Shadows of the Empire and the iconic Thrawn trilogy. Expectations are high, and the stage is set for the best STAR WARS movie yet. Fortunately, everything turned out well. </p> <p> <strong>I like the Phantom Menace.</strong> It is something I was always open about, and after watching the movie <em>The People vs. George Lucas</em>, I knew I would write this blog one day. It was a really good interview-style documentary about STAR WARS fans who (among other things) didn't like The Phantom Menace. Consider this blog my reaction to their testimony. </p> <p> Many people's disappointment stemmed from the explanation of how the Force works. During the original trilogy, it was described as: <em> "an energy field created by all living things. It surrounds us, penetrates us, and binds the galaxy together." </em> From a certain point of view, this is anoter well-played hand from Bens side. Manipulating a naive farmer into your pseudo-religion doubles down on Bens character from the Episode V as well as the ways of the Jedi seen in the Episode I and rest of the prequels. With each new movie, people learn that late Old Republic Jedi were not the good guys like described in originals.[*] </p> <p> The sudden appearance of midichlorians and the revelation of the Jedi's true nature are elements that don't align with the story of the original trilogy. Inconsistencies in fictional worlds can harm a brand's perception. However, expecting consistency in STAR WARS is a big stretch. The story was originally meant to be a standalone movie, but as soon as Lucasfilm smelled money, it was immediately renamed Episode IV. STAR WARS has been constantly changing, with alternative sequels, the removal of some materials from canon, and even changes to world elements like the Jedi's Kendo-inspired fighting style. </p> <p> <em>Regarding Jar Jar...</em> I see strong parallels between his character and R2 & 3PO from the beginning of Episode IV. It isn’t exactly high sci-fi when you watch two robots arguing in the desert, expressing their feelings about each other. Yet, many people are disappointed that Episode I is too oriented toward a younger audience. This critique of a space fairy tale not being "adult enough" is often followed by complaints that it brings up too much politics. It's a paradox I just can't follow. To me, both the droids and the Gungan are just jesters in a technically exceptional Flash Gordon derivative. </p> <p> Personally, I applaud the movie for exploring a time so close to A New Hope yet so different, as we witness the final years of the noble Galactic Republic. We finally see the Jedi Temple and its questionable role in maintaining galactic peace, as well as the harsh reality of how impoverished worlds remain untouched by the ruling apparatus in both eras. We see how the actions of unlikely heroes shape the lives and world around them - just like in every STAR WARS story before. Visually, the movie feels sleek and new with its advanced CGI, yet the set design and costumes still resemble the 1970s Ralph McQuarrie style. This is especially evident in the design of the Naboo starships. </p> <p> <em>But</em> if there’s any letdown from my side, it's that they could have expanded a bit more on the different Jedi training schools that Obi-Wan and Qui-Gon practiced. The only hint was their saber colors, which is fine, I guess, but they could have spared a few words here and there about how the way of the Force is interpreted differently by each student. Then again, one should realize that the whole concept of "training schools" is more of an afterthought, since the saber colors were originally changed just to visually fit the scenery. In Episode VI, Luke originally had a blue lightsaber, but it didn't stand out against the blue sky of Tatooine, so they changed it to green. </p> <p> Lastly, there's the Phantom Cut - <em>The</em> fan edit that streamlines the movie by cutting a few scenes with Jar Jar, some of the politics, and even the midichlorian explanation. I personally liked that the part where Queen Amidala asks for the <em>name</em> of the droid that repaired the ship was removed. (Why would she do that anyway?) The edit is also slightly sped up to reduce the runtime and make the movie feel less static. All in all, the Phantom Cut is nice and definitely worth checking out if you don't like the idea of the Force emitting bacteria. </p> <p> All I'm saying is that you should enjoy the movie for what it is and not try to look too deeply into something with the depth of a glass of Bantha milk. </p> <p><img src="https://dpolakovic.space/blogs/pics/phantom4.png" alt="a generic star wars picture"></p> <br> <hr> <em> <p> <p> * There is this very well dubbed Episode I fan/fun edit called The Jedi party. It portrais Jedi as arogant trouble makers and it's actually one of the best STAR WARS community projects I've seen in a long time. You can check it out <a href="https://www.youtube.com/watch?v=WSCm8yAxBr8">here</a>. </p> <br> </em>
+ ]]></content:encoded>
+ </item>
<item>
<title>Y292B bug</title>
<link>https://www.dpolakovic.space/blogs/y292b</link>
<description>We're doomed! Again...</description>
<pubDate>Wed, 26 Jun 2024 17:00:00 GMT</pubDate>
+ <author>David Polakovic</author>
<image>https://www.dpolakovic.space/blogs/pics/bug.jpg</image>
<pos>100% 0</pos>
+ <content:encoded><![CDATA[
+ <img src="./pics/bug.jpg" alt="TITLE"> <p> Timekeeping is bitch. I found out the hard way while trying to program extendable time keeper for other celestial bodies in the Solar system. The problem is that, every calendar system is flooded with so many rules and exceptions that the calendar builder basically becomes another programming language. I am well aware of the Zawinski's Law* however, I wanted to avoid creating another Emacs. </p> <p> Common timekeeping obstacles include inconsistent leap intervals, ever changing time zones and conversions from one timekeeping system to another. In addition to these algorithmic problems, there are device limitations like precision of the oscilator or memory capacity. In modern age, these are usually overlooked, especially memory allocation is not considered a serious problem since the <em>Y2K bug</em> came and went. </p> <p> <em>Y2K</em>, <em>Y2038</em> and other Y2xx bugs are not really "bugs" but simple overflow of reserved memory space. You see, Unix and unix-like computer systems measure time by incrementing seconds in single integer variable <em>time_t</em>. Naturally, this timekeeping is named the <em>Unix time</em> and its 0 is equal to midnight, 1st of January 1970. <p> Different implementations of the Unix time, use different data type for <em>time_t</em>. When the data type reaches its upper limit, it will "flip", either to its opposite (negative) value or to the 0. Current, main branch of the Linux kernel uses signed 64-bit integer. This solution has rollover point in year 292,277,026,596. That is roughly 292 billion, 277 million, 24 thousand years into future. </p> But then what? <p> The number overflows and the date will jump back 278 billion years before the Big Bang**? Needles to say, this needs to be fixed. Luckily, we have 33 life times of our Sun to solve this problem but we could propose some solutions even today. The obvious solution is to use dynamically typed language. </p> #!/usr/bin/perl<br> use strict;<br> use warnings;<br><br> my $time_f = 9223372036854775809; # out of long int range<br> my $year_s = 31536000; # seconds in year<br><br> while (1) {<br> my $year = int($time_f / $year_s + 1970);<br> print "unix time: $time_f \tyear: $year\n";<br> $time_f++;<br> #sleep(1);<br> } <!-- perlcc -O time_f.pl --> <p> Problem solved. Devoted fans of parentheses can use Lisp. Now the variable will increment indefinitely with only limitation being the physical memory. The <em>time_f</em> (f stands for fix) can consist of slightly over 1 billion <em>digits</em> per 1GB of memory. However, Linus Torvalds would rather use Debian than program in anything other than C, so if we want to put this into the kernel, we need to get more static. </p> #include <stdio.h><br> #include <stdlib.h><br> #include <string.h><br> #include <gmp.h> // GNU Multiple Precision Arithmetic Library<br><br> int main() {<br><br> mpz_t time_f, year_s, year;<br> mpz_init(time_f);<br> mpz_init(year_s);<br> mpz_init(year);<br><br> mpz_set_str(time_f, "9223372036854775809", 10); // out of long int range<br> mpz_set_str(year_s, "31536000", 10); // seconds in year<br><br> while (1) {<br> mpz_tdiv_q(year, time_f, year_s);<br><br> gmp_printf("unix time: %Zd", time_f);<br> gmp_printf("\t\tyear: %Zd\n", year);<br><br> // Increment unix time by 1<br> mpz_add_ui(time_f, time_f, 1);<br><br> }<br> return 0;<br> }<br> <p> In C, we can utilize the <em>GNU Multiple Precision Arithmetic Library</em> which will allow us to dynamically allocate memory for variables. Unfortunately, the <em>gmp.h</em> is not compatible with kernel space, so we will need to design this heresy from scratch. </p> <p> For dynamic memory allocation in C we can use arrays. Then with strings we can read numbers beyond <em>long long int</em> just like with the <em>gmp.h</em>. It would be also nice to create a division function for converting seconds into reasonable time units, like years. </p> <p> Let the structure <em>BigInt</em> represent large integers with arbitrary precision using an array of digits. </p> typedef struct {<br> int *digits; // Pointer to an array of digits<br> int size; // Number of digits<br> } BigInt; <p> Then we need to initialize the <em>BigInt</em> from the string input. </p> BigInt initBigInt(const char *str) {<br> int len = strlen(str); // Get the length of the string<br> BigInt num; // Declare a BigInt variable<br> num.size = len; // Set the size of BigInt to the length of the string<br> num.digits = (int *)malloc(len * sizeof(int)); // Alloc memory for the digits<br> for (int i = 0; i < len; i++) {<br> num.digits[i] = str[len - 1 - i] - '0'; // Convert digits to int and store them in reverse<br> }<br> return num; // Return the initialized BigInt<br> } <p> And of course, we need to free the memory like all good mannered people. </p> void freeBigInt(BigInt *num) {<br> free(num->digits);<br> num->digits = NULL;<br> num->size = 0;<br> } <p> When we have our structures fully defined, we will use them to feed variables with values. </p> int main() {<br> BigInt time_f = loadCurrentUnixTime();<br> BigInt year_s = initBigInt("31536000"); // Seconds in a year <br><br>...<br> <p> Now we can focus on the long division. This part was little bit problematic for me because of two reasons. C isn't my preferred language*** and as I found out, the long division is taught differently all over this planet. It seems that I have learnt the <a href="https://en.wikipedia.org/wiki/Long_division#Eurasia"> Germanic-Euroasian method </a> which is little bit different than the method tought in english speaking countries. (Turns out, math ain't such universal language after all...) Anyway, with the help of my elementary school notes and one C book from local library, I managed to spit out next division function. </p> void divideBigInt(BigInt *dividend, BigInt *divisor, BigInt *result) {<br> // Initialize result size and allocate memory for its digits<br> result->size = dividend->size; <br> result->digits = (int *)calloc(result->size, sizeof(int));<br><br> // Initialize help BigInt named current<br> BigInt current;<br> current.size = 0;<br> current.digits = (int *)calloc(dividend->size, sizeof(int));<br><br> // Fill the "current" helper var<br> for (int i = dividend->size - 1; i >= 0; i--) {<br> // Shift digits in the "current" to the left<br> for (int j = current.size; j > 0; j--) {<br> current.digits[j] = current.digits[j - 1];<br> }<br> // Add the next digit from dividend to the "current"<br> current.digits[0] = dividend->digits[i];<br> current.size++;<br><br> // Remove leading zeros in the "current"<br> while (current.size > 1 && current.digits[current.size - 1] == 0) {<br> current.size--;<br> }<br><br> int count = 0;<br> // Do division until the "current" is less than the divisor<br> while (isGreaterOrEqual(&current, divisor)) {<br> BigInt tempResult;<br> // Subtract divisor from the "current"<br> subtractBigInt(&current, divisor, &tempResult);<br> free(current.digits);<br> current = tempResult;<br> count++;<br> }<br><br> // Store the quotient in the result<br> result->digits[i] = count;<br> }<br><br> // Remove leading zeros in the result<br> while (result->size > 1 && result->digits[result->size - 1] == 0) {<br> result->size--;<br> }<br><br> free(current.digits);<br> } <p> With addition of few more functions to monitor the progress, I was able to get output for current Unix time and fictional with over 400 digits too. </p> <p> The next logical step would be to modify it to fit the <em>time.c</em> in the Linux kernel, however, my knowledge of kernel-space programming is converging to a zero. Also, I am not sure how will the division function handle prime numbers larger than <em>long long int</em>. </p> <p> Anyway, the <em>fixed.c</em> is published under GPLv3 and available <a href="https://git.dpolakovic.space/?p=unix-time-fix;a=tree">here</a> for anyone who wants to fix the Y292b problem on a kernel level for future generations. Good luck and remember, the time is ticking. </p> <br> <img src="./pics/win-xp2.png"/> <h3>Update</h3> <em>5 Jul 2024</em> <br> <p> Usually, I tend not to update my blogs as I believe every post is a product of its time and circumstances, but today I will be the George Lucas of obscure web writings. My email inbox got quite flooded with all kinds of responses to this <em>not</em> bug <em>not</em> fix proposition, so I wanted to make some things straight. </p> <p> First of all, the post was written with a funny attitude, but it is in no way meant to be a joke, parody, or insult. Quite a lot of people understood what I meant by this software complete solution to an integer overflow problem and the tradeoffs of it. I still believe that such a solution could be implemented in some optional kernel module. (And not only for timekeeping). </p> <p> Secondly, I know the linked demo has some optimizations to be done; for example, the digits of <em>BigInt</em> should be <em>byte</em>, not <em>int</em>. However, I want to emphasize that this is just an algorithmic demo, not finished code. </p> <p> Lastly, I want to address something that was not mentioned many times but felt tough to read nevertheless. I was not ordering people to immediately start working on this. The sole reason why I posted this to the Linux Kernel Mailing List was to inspire people with sufficient skill in kernel space to look into this unconventional idea. And I still believe that there must be someone who will try this out of curiosity - like in the old days. </p> <p> I hope this will make less people angry. </p> <br> <hr> <em> <p> * Zawinski's Law is fictional law in computer science that mocks the inevitable feature creep, stating that every program will eventually try to read email. Please note that the law was formulated during 90's, hence the email feature. I also found good website with more <a href="https://www.laws-of-software.com/laws/zawinski/">computer science laws</a>. </p> <p> ** In <a href="https://www.youtube.com/watch?v=rFVdueuDD_o">this vlog</a> Mr. Tyson mentions that time is not really relevant before the Big Bang. He proposes that before this point, time as now known concept might not even exist. To me, it is very interesting to think about time this way. </p> <p> *** Even though I can appreciate the speed and direct control of the code, I still want to write code that is little bit more intuitive. But since by that I mean Pearl, I guess this all boils down to a personal preference. </p> <br> </em>
+ ]]></content:encoded>
</item>
<item>
<link>https://www.dpolakovic.space/blogs/windows-95-printer-hack</link>
<description>Start me up!</description>
<pubDate>Fri, 12 Apr 2024 16:00:00 GMT</pubDate>
+ <author>David Polakovic</author>
<image>https://www.dpolakovic.space/blogs/pics/deskjet710c.jpg</image>
<pos>100% 5</pos>
+ <content:encoded><![CDATA[
+ <img src="./pics/win95.png" alt="TITLE"> <!--<img src="./pics/deskjet710c.jpg" alt="Windows 95 Logo">--> </p> <p> During my daily web crawl I encountered a very interesting <a href="https://3.bp.blogspot.com/-XniWAeMJJgg/UQ4eaEr5RlI/AAAAAAAAPAA/7ftwZg4Bqcg/s1600/Win95_hack.gif">[ɡɪf]</a> that I haven't seen in a long time. It was a hack of an unspecified version of Windows 95, which showed how to bypass the login screen with the help of the menu and printing dialog. However, after a brief check, I found a fair amount of people stating that "just hitting the cancel" button would do the same. Sharp-eyed viewers would notice that it was the very first action taken in the picture. In order to find out if the hack is real at all, I decided to reproduce it and document it for the good of the internet. </p> <h3>Analysis</h3> <p> The Windows 9x family ran on FAT file-system which does not support permission models. It was originally used for floppies and later for other portable media where permissions are simply not desired. You wouldn't want to throw away a perfectly fine floppy just because you can't delete the file on it from your Solaris machine... This means that all access rights on 9x's are managed on the OS level only. </p> <p> In addition, a new user can be added simply by entering new credentials on the login screen(!). While in the OS itself, users can encounter 4 types of "permissions": <em>read-only, hidden, archive</em> and <em>system</em>. However in standard terms, every user had <em>read</em> and <em> execute</em> permissions. And since all users can <em>execute</em> the files with the <em>archive</em> permission, like <em>File Explorer</em> for example, they can easily change the <em>read-only</em> attribute to false, de facto giving them the <em>write</em> permission too. </p> <p> However, the login dialog shown in the picture was for a network and that's where things might get tricky. Accessing the client-server network does in fact require credentials, even on the 95. To crack the setup of Windows NT 5.31 Domain Controller is beyond scope of this OS hack, but a user who has accessed the machine might just have enough tools to get in the network as well. </p> <h3>Prerequisites</h3> <p> I used a virtual machine since I don't have much hardware to spare. Here is my setup and everything needed to reproduce it. </p> <p> Host machine <a href="https://www.virtualbox.org/wiki/Linux_Downloads">VirtualBox 6.1.50 r161033 (Qt5.15.8)</a><br> <a href="https://www.debian.org/News/2024/20240210">Debian 12.5</a><br><br> Virtual machine* <a href="https://winworldpc.com/product/windows-95/rtm">Windows 95 RTM (4.00.950)</a> (FAT16)<br> <a href="https://winworldpc.com/product/windows-95/osr-3">Windows 95 OSR2.5 (4.00.950 C)</a> (FAT32)<br> <a href="https://winworldpc.com/product/microsoft-windows-boot-disk/95-osr2x">Windows 95 Boot Floppy</a><br> <a href="http://www.lonecrusader.x10host.com/fix95cpu.html">FIX95CPU</a><br> <em><a href="https://archive.org/details/hp-desk-jet-710-c-series-printer-software-ver-10-3">HP DeskJet 710C Series driver v10.3</a></em><br><br> </p> <p> I started with Windows 95 v4.00.950, the very first release. As a rule of thumb, if there are going to be bugs, they are likely to appear in the initial version. The 4.00.950 C is a somewhat special version. It is the final release of the 95 with some features which will come handy later. The boot floppy is needed only for installation, and the FIX95CPU is necessary if your host has an equal/faster CPU than 2.1 Ghz. </p> <h3>Preparation</h3> <p> After a fresh install, every user profile shares the same machine, from folders to settings. In order to set up the user profiles, navigate to the <em>Control Panel > Passwords > User Profiles</em> and check the <em>Users can customize their prefferences...</em> option. Make sure to check two more checkboxes from <em>User Profile Settings</em> to include the network preferences. After a restart, every new user that logs in can customize his machine to their needs. Now we can focus on the printer. </p> <p> Windows 95 offers quite a lot of drivers for various printers. You can check the list of printers in the <em>Control Panel > Printers > Add Printers</em>. However, the HP DeskJet 710C is not included. Closest match with this device is HP DeskJet 560C which will work just fine. After all, every HP printer ending with the letter "C" (and only "C", not "C/PS") will work too. The "C" stands for "Color", and it is the color printer's <em>Printing Properties</em> dialog which we will exploit.** </p> <p> The next step would be to connect the VM to simple a peer-to-peer network. In the network properties, enable the <em>File and Print Sharing</em>. Then we need to add a new protocol as a <em>component</em>. Pick <em>Microsoft</em> as the manufacturer and select the <em>TCP/IP</em> network protocol. When done, open the protocol properties and on the <em>IP Address</em> tab add the IP address of your choice. Upon saving, the machine will restart again. </p> <p> In VirtualBox, navigate to network settings of the VM and enable the network adapter, attach it to <em>Internal Network</em> and in advanced options pick <em>PCnet-FAST III (Am79C973)</em> adapter. Set the <em>Allow All</em> in <em>Promiscuous Mode</em> option. Now we can clone the machine. Then, for the newly cloned machine, make sure to: <ul> <li>generate new mac address in VirtualBox network settings</li> <li>change the machine name in Windows 95 network properties under <em>Identification</em> tab</li> <li>change the host identifier (last number) of the IP address in <em>TCP/IP</em> properties</li> </ul> </p> <p> You can now start both VMs. Create a new folder on one machine and share it on the network via folder <em>Properties</em>. If everything was done correctly, you should see both VMs in Windows 95 <em>Network Neighborhood</em>. </p> <p> Lastly, the client-server network. We don't actually need to create new a Windows NT 3.51 server VM, because we can simulate its presence by registry edit. When disabling the <em>Cancel</em> button, Windows will try to validate the user input with the server. Unless all three, username, password and domain name, aren't checked with the server, the user won't be let in the system. It's the same registry edit shown in the original gif. Obviously, without the presence of any server, we will lock our selves out of the system, so I recommend creating a VM snapshot before the next step. </p> <p> In <em>regedit</em> navigate to <em>HKEY_LOCAL_MACHINE > Network > Logon</em>. Open <em>Edit</em> menu pick <em>New > DWORD Value</em>. In the right pane, a new empty line will be added. Enter <em>MustBeValidated</em> and then <em>Modify</em> the value. In a new dialog, change the current value <em>0</em> to new <em>1</em>. After another restart, users will not be able to "cancel" the login prompt. </p> <h3>Test</h3> <p> Login into Windows 95 virtual machine with the user name "Bill" and password "Gates". This user has a shared folder on the peer-to-peer network named "Halloween files" which contains one file called "secret.txt". Then start up the second VM of which we don't know any credentials. </p> <p> At the login prompt click the <em>?</em> button and then the <em>Cancel</em> button. A help message will appear stating: <em> Closes this dialog box withput saving any changes you have made. </em> Right-click the message and choose the <em>Print Topic...</em> option. A <em>Print</em> window will appear. Make sure to select the HP DeskJet printer which has the letter <em>C</em> in the name and click the <em>Properties</em> button. </p> <p> A new window with <em>ColorSmart(tm)</em> options will appear. Click the <em>Help...</em> button. On the new <em>HP DeskJet</em> help window menu bar pick options <em>File > Open</em>. A new <em>Open</em> window will appear. Next to the <em>Look in:</em> combobox press the <em>Up One Level</em> button (the one with the folder and arrow on it) until you get to the <em>Desktop</em>. Right click <em>My Computer</em> and select <em>Open</em>. </p> <p> We are allowed into the system as default nameless user. Partially... The <em>Desktop</em> is not responsive, however the <em>Start</em> menu works and therefore the <em>Run...</em> does too. Also, the login prompt <em>Enter Network Password</em> is still present. </p> <p> What now? </p> <p> Now we can easily revert the system hardening we've done during the preparation phase. Using <em>rgedit</em> we navigate again to the <em>HKEY_LOCAL_MACHINE > Network > Logon</em>. Since we are still logged as <em>null</em> profile, the registry will be in the default state, without the DWORD value we've added. We will add it again but this time we will keep the value <em>0</em>. After that, we will be able to close the login prompt. </p> <p> Let's open the <em>Start > Find > File or Folders</em> and enter the "pwl". Results will list the <em>Bill.pwl</em> file that contains the login credentials for the user Bill. Copy it on the <em>Desktop</em> or anywhere safe and then delete it from its original location. Right now we can insert the <a href="https://archive.org/details/microsoft_cd-rom_extras">Microsoft Windows 95 CD-ROM Extras</a> floppy number 5. This floppy contains the <em>PWLEDIT.exe</em> which can now decrypt the passwords from the <em>.pwl</em> files we saved.*** </p> <p> When we run <em>PWLEDIT.exe</em> we will be asked to enter the password for the user from new login prompt pop-up. Since we deleted the users <em>.pwl</em> file from <em>C:\Windows</em>, we can assign new password to mentioned user. After this action, a new <em>.pwl</em> file will be created in <em>C:\Windows</em> with new password, and the <em>PWLEDIT</em> window will open. We can use it to decipher the password for the client-server network. </p> <p> <h3>Conclusion</h3> <p> The hack is real! It offers enough tools to gain access to the machine, peer-to-peer network and client-server network as well. A question arises. Will it always work ? Sadly, no. </p> <p> The printer hack itself will work, but when you disable password caching in the registry editor, you won't be able to access any network, since the <em>.pwl</em> files won't be stored anymore. This is "solved" however, in later releases. You see, the very last Windows 95 release I mentioned in prerequisites, offers the <em>Users</em> option in the <em>Control Panel</em>. This allows us to change the password for user profiles and therefore gain access to the peer-to-peer network. The situation is same on 98FE and 98SE too. No luck for the client-server network. Once there is nothing to decrypt, you are stuck. </p> <p> There is, of course, a way how to perform this hack without a printer - through the power of MS-DOS prompt. By pressing <em>F8</em> during startup, you could enter the <em>MS-DOS mode only</em> where you can utilize the <em>regedit</em> command. This will require the knowledge of locating the registries in the system files. I can not emphasize how awful work it is, but I would rather go to get the physical DeskJet 710C than edit registries with the DOS prompt. </p> <br> <p> <!--<img src="./pics/win95.png" alt="TITLE">--> <img src="./pics/deskjet710c.jpg" alt="The printer that started it all..."> <!-- I don't know man... I would switch those pics other way around but everybody keeps sayin it is better this way... --> </p> <br> <hr> <em> <p> * I prefer to use VirtualBox because I am unable to make QEMU/KVM work, since I am not a rocket scientist. I don't see the advantage of a package manager when I have to edit random config files and hunt for tutorials. Why this can't be managed by APT or explained by the developer/maintainer? Seriously, why this needs to be another Wine-like experience is beyond me. </p> <p> ** If you want to install the 710C after all, you will encounter a few problems. The HPDJ710C.INF file prevents the driver from being installed by the "Add Printer" dialog and the HP's installation wizard requires a physical device to be connected via parallel port. The workaround may be manually (re)placing the HPFPNP.DLL, and any other files the driver requires, in C:\Windows\System. Honestly I don't know, but I will update this when/if I find out. </p> <p> *** This was an official Microsoft tool, which you could freely download from <a href="">http://www.microsoft.com/windows95/admintools.htm</a> </p> <br> </em>
+ ]]></content:encoded>
</item>
<item>
<link>https://www.dpolakovic.space/blogs/zork</link>
<description>A hollow voice says "Fool".</description>
<pubDate>Fri, 24 Nov 2023 20:00:00 GMT</pubDate>
+ <author>David Polakovic</author>
<image>https://www.dpolakovic.space/blogs/pics/zork.png</image>
<pos>100% 1</pos>
+ <content:encoded><![CDATA[
+ <img src="./pics/zork.png" alt="Zork box art"> </p> <p> Recently I saw a rerun of The Big Bang Theory on TV. It was quite refreshing since I don't rewatch any series, with the only exception being Black Books. One of the aired episodes that day was the one where Sheldon mentions playing a buggy beta version of Zork[*]. Suddenly, I remembered that I wanted to try out this old text adventure since I watched the episode back in 2010 or so. I considered it super weird then to play videogames without the... well, video part. But I played many tabletop RPGs since, so I am now well aware of using imagination as a game mechanic. And I've seen Zork appear many times on online forums and even in Call of Duty Black ops which I played on Xbox360. So I assume this rerun was the last straw and the "call to adventure" I was waiting for. Let's start with preparation for the descent. </p> <p> Firstly, we will need to <a href="https://eblong.com/infocom/#zork1">obtain the game</a> and <a href="http://infodoc.plover.net/manuals/zork1.pdf">the manual</a> might also come handy. (If you already have ZORK I, you can <a href="#play">jump here</a>.) For enjoyers of adavnced LISP, I include source code for the <a href="https://github.com/historicalsource/zork">Infocom version</a>, <a href="https://github.com/MITDDC/zork">MIT release</a> as well as the <a href="https://github.com/heasm66/mdlzork">mainframe versions</a>. And in order to actually use game files, we will need package <em>frotz</em>. sudo apt install frotz Frotz is licensed as free software under GPLv2+ but you won't find it in the Free software directory. I tried to contact its maintainer David Griffith about this issue, but recieved no answer so far. But the frotz source code is available <a href="https://gitlab.com/DavidGriffith/frotz">here</a> for every Z-machines enthusiasts which favors Graham Nelson's specification standard 1.0. </p> <p> Anyway, we will use frotz interpreter to run the game files. Don't forget to use the full path to the directory where you downloaded or moved the game files. A <em>Games</em> directory at the home might be a good idea. frotz ~/Games/zork1-r88-s840726.z3 We can also make an alias in your <em>.bashrc</em> file to start the game from everywhere. Or... we can unleash our inner hacker and create a bash script that will run any version of Zork we downloaded simply by argument. </p> <p> #!/bin/bash<br><br> # Define a dictionary of aliases<br> declare -A dictionary=(<br> ["r2"]="zork1-r2-sAS000C.z1"<br> ["r15"]="zork1-r15-sXXXXXX.z2"<br> ["r88"]="zork1-r88-s840726.z3"<br> ["r52"]="zork1-invclues-r52-s871125.z5"<br> # You can add more zork versions here<br> )<br><br> # Check if the correct number of arguments is provided<br> if [ $# -ne 1 ]; then<br> echo "Usage: zork <version>"<br> exit 1<br> # Or we can hard code any version to be default e.g.<br> # cd ~/Games/ && frotz zork1-r88-s840726.z3<br> fi<br><br> # Check if alias exists in the dictionary<br> alias="$1"<br> file="${dictionary[$alias]}"<br><br> if [ -z "$file" ]; then<br> echo "Zork version '$alias' not found."<br> exit 1<br> fi<br><br> # Cd to your directory where you store the game files<br> #<br> # note:<br> # you could use full path to file with frotz command<br> # but your saved game files would be then stored at ~<br> cd ~/Games/<br><br> # Profit!<br> frotz "$file"<br> In order to run this script from everywhere in our file system, we will save it under name <em>zork</em> (without ".sh") and move it into our bash PATH. For me it will be <em>~/.local/bin</em> . After that we will need to "chmod-ex" our script to make it executable. </p> <p> chmod +x zork And now we can run any version of Zork we like by using the release number of desired version as argument for our script. </p> <p> zork r52 </p> <p> This script can come in handy as different builds have different bugs and command responses. The first two versions (r2 and r5) will teleport player to a random location when a nonsense travel command is given, like GO WALL or GO TREE. In all versions except for <em>solid gold</em> (r52) you can pour water from the bottle even if the bottle isn't open. And every version suffers from EXAMINE OVERBOARD problem. You can check the full list of differences in <a href="http://graeme.50webs.com/infobugs/zork1.htm">Infobugs</a> and <a href="https://www.microheaven.com/InfocomBugs/zorki.shtml">Microheavens</a> zork sections. Exploiting those older buggy versions sounds fun and I, as a real adventurer, picked up release r15 the "Hack of 15.UG3AU5" version. </p> <p> The game itself is pretty straight forward. Our adventure takes place circa 300 years after the fall of the Greatest Underground Empire, and we take the role of nameless adventurer seeking fame and fortune in the ruins of the once unmatched empire. The manual explains that the game is played by typing commands and awaiting the response from the game. It is basically a Read Eval Print Loop with a complex parser and a score system. And just like any REPL, Zork counts your lines - in this case, commands or actions. The goal is to retrieve treasures and <em>put</em> them into the <em>trophy case</em> with the least actions possible. The more we return, more we score. The manual gives no information on how many treasuers are out there or if we lose when we waste too many turns. However, it mentions five times to draw a map as we play, so I will. </p> <p> <em>Let's play.</em> </p> <p> <br> ZORK: The Great Underground Empire - Part I<br> Copyright (c) 1980 by Infocom, Inc. All rights reserved.<br> ZORK is a trademark of Infocom, Inc.<br> Release 15 / Serial number ââââââ<br><br> West of House<br> You are standing in an open field west of a white house, with a boarded front door.<br> There is a small mailbox here.<br> ><br> I fire up the zork script and I start by reading a leaflet from the mailbox, leading me nowhere. But after the first one hundred valid actions, I managed to map the surroundings of the house, locate the trophy case, find a sword and get a lamp with a terrific score of 10. The last thing to point out in this location might be the <em>wooden door with strange gothic lettering</em> in the living room of the house, which is worth looking into. I will leave this intentionally blank. It is time to move elsewere. </p> <p> I found a canyon to the east of the house, so I went there. I arrived at the canyon view and continued to the west through the forest. I stopped next to the big tree with suspiciously looking lower branches. This is a hint. After climbing the tree, I found a bird's nest with a jewel-encrusted egg. What a luck! I grab it and run with it to the trophy case before it's <em>rightful owner</em> comes for it. (I have a feeling that it is not the bird.) On my way back I got lost a little in the forest, but somehow I appeared in the clearing behind the house. Jumped through the kitchen window, spent some time (turns) trying to <em>put</em> the egg jewel into the trophy case and... Success! First treasure collected, 10 score earned, totaling on 20 right now. </p> <p> So far so good. The forest on the east had a few more roads to go, but I am not sure if I got lost because of some glitch or if the forest was too thick. Either way, I exit the house and march to the west this time. <em>One hundred moves later</em>... Dead end, just like the canyon on the east and forests on the north and south. I am going back to house to regroup and look for more clues. After further examination of the house, I see only a chimney in the kitchen and a rug in the living room. I bet on a rug as it nicely ties the room together. "With the rug moved, the dusty cover of a closed trap-door appears." I hastily open the trap-door and descent into the darkness. The score jumped to 25 points. </p> <p> With someone's help, the trap door closes above my head. I am in a dark cellar and the ancient sword starts to glow a little. Tension rises. As I put my foot in the room to the north, a nasty-looking troll blocking my way out. First enemy encounter. The troll seems to be wielding an axe and my sword glows very brightly now. I charge the troll, but he nimbly jumps away and reaches me with his ax. The game responds with <em>Ouch!</em> so I assume it is just a flesh wound... </p> >attack troll with sword<br> Your sword misses the troll by an inch.<br> The flat of the troll's axe hits you delicately on the head, knocking you out.<br> The troll hesitates, fingering his axe.<br> Conquering his fears, the troll puts you to death.<br> It appears that that last blow was too much for you. I'm afraid you are dead.<br><br> **** You have died ****<br> It wasn't a flesh wound after all. <p> Never mind I restore the game, enter the room again and after a long fight troll dies with another swing of my blade. As soon as he breathes his last breath, his body disappears in sinister black fog and my sword is no longer glowing. My score is 45 now, but as I try to lift his blody axe, I realize my inventory is full. I'll stick with the sword. </p> <p> As I look around, I see labyrinth to the west and a long passage to the east. I try to circle the cellar I came from, which leads me to the Mirror room. In it, there is only a mirror which seems to be responding to touch but nothing else. Two other exits from the room lead to the same cave, making it the dead end with the only way down into the cave. But as I try to leave the mirror room I realize that this is not the same passage I came in... It took me a lot of reloads (<em>restores</em>) to realize that the mirror is a portal to another mirror room. </p> <p> I am redrawing my map and teleporting back to the first mirror room, which I mark with a letter "A" now. The map is starting to look very complicated, and it's much bigger than I expected. I have the temptation to draw it in some visual tool on PC but for now I am staying OG with pencil. I haven't found anything of value so far and I am afraid to go on this new mirror branch so soon. </p> <p> I return back to the first room, cellar, and try to focus on going another direction than east as it, too holds many rooms. I go south and enter the gallery. A loot at last. But then, out of nowhere I spot somebody in the room with me. He says nothing, but holds a bag. At this point I have no idea what to do. I am not sure if I can say something (in this game) but I just don't want to attack someone who is not hostile to me. I am reaching for the manual. There is mention of both <em>say</em> and <em>tell</em> keywords on page 19, but the game doesn't recognize them somehow. This might be a trait of my buggy build. Nevermind, I try waving. Not working. I will wave my glowing sword, showing I am armed and dangerous. Nothing. As a somewhat veteran of D&D I will try one last effort to stay civilized - <em>wait.</em> </p> >wave hand<br> I can't use the word 'hand' here.<br> >wave sword<br> Waving the sword isn't notably helpful.<br> >wait<br> Shifting in the midst of a thrust, the thief knocks you unconscious with the haft of his<br> stiletto.<br> The thief entertains himself by rifling your pack.<br> The thief, who is essentially a pragmatist, dispatches you as a threat to his livelihood.<br> It appears that that last blow was too much for you. I'm afraid you are dead.<br><br> **** You have died ****<br> I guess peace was never an option... <p> I restored from the last save point in the circle room and run straight to the gallery. I enter the room with sword in my hand, but the room is empty(?). I will spare you of my hundreds of reloads but it works like this. The thief shows up whenever you pick up or come to something worth points. He will take it whether it is in a room or on you. You can fight him but I was out of luck. I tried knife, but that was doing no damage at all, sword performed best but he was always quicker than me and troll's ax hit him too, but after first hit he stole my stuff and left. Command <em>follow thief</em> doesn't work - boy I hate him. But I was able to "bug him out" by taking the painting, saving and restoring the just saved game. He didn't come back. </p> <p> But still, my inventory is getting full, and I will have to carry things out to the trophy case. So the new plan is to look for a way out and then try to scavenge for other valuables. And nothing screams more "way out" than a maze. I go back to the cellar (again), this time with painting and enter the maze to the west. I will mark down all of my moves on separate sheet of paper and drop items to be my breadcrumbs. And I will save often, just in case the old friend shows up. </p> <p> I managed to navigate myself to the treasure inside the maze. It is the skeleton key and the bag of coins. Score is 64. I do know my way back, but I need to get out another way, hopefully leading me to the house again. I managed to navigate to the room with evil cyclops. I must say that the whole maze solving took me about 1,5 hours of which I had to deal with thief at least 10 times. I am more than ready to kill the beast standing before me or die trying. I charge the monster and after a tough one-sided battle... </p> >attack cyclops with sword<br> The cyclops shrugs but otherwise ignores your pitiful attempt.<br> The cyclops, tired of all of your games and trickery, eats you. The cyclops says 'Mmm. Just<br> like Mom used to make 'em.'<br><br> **** You have died **** Dead, thanks to nobody's favorite X-men character. <p> Ok. New plan. Don't leave the sandwich in the maze and let's try to bribe the cyclops with it. At this point, I knew how to solve the maze from the top of my head. I face the beast again, this time without the sword, holding only a small sub with peppers. He likes my proposition and takes my bottle with water too. The beast falls asleep after a good lunch. I tried to look around the room and I saw stairs up, but as soon as I enter the treasure room on the upper floor... the thief, again. I am carrying the painting, the bag of coins and just in front of our eyes, there is a beautiful silver chalice.The score is 79 and it is time to play his own game. </p> <p> I gave him my sword. He is stunned by this gesture and examines the weapon. Then suddenly, out of nowhere, I sneak behind him and struck him dead with knife from the attic. Well, it was like three attacks but nevertheless RETRIBUTION! With the thief dead, I take my sword back and drop the knife as insturment of a cold murder. Then there is the silver chalice lying on the ground, but I am unable to take it as the inventory is full. I want to drop the garlic, but I am not sure if this underground is vampire-free, so I will stick with the garlic and I drop the rope. I am sure I won't regret it later... The score is just one point short of 100. </p> <p> Sadly, no exit from the treasure room and cyclops room is also a dead end. My patience is slowly fading away and I access the World Wide Web for hints. I found a pretty nice map which told me that there was another way out of the maze. It's the cryptic grating room from clearing next to the house! I close the map and rush to it. But yeah, the grating is locked and I left the skeleton key inside the maze... Went back for the key, emerged on the surface and delivered the treasures back to the living room in 2 rounds because of a small inventory. Score is sitting way up on 115. </p> <p> And right now, I am considering ending this adventure as the score is above 100 and my lust for retro gaming has been somewhat satisfied. I typed <em>score</em> to see that I reached the rank of Junior Adventurer, which is <a href="https://ganelson.github.io/inform-website/book/WI_9_3.html">4th rank out of 8</a>. As much as I want to say that it was fun, I feel tricked into playing a puzzle game with very little adventure in it. The lack of usefull information and overall "story" puts this game on the same level as some rogue-likes. It is good but not something I can see falling into. At least not now. If you consider playing it, here are my key takeaways from this short gameplay: <ul> <li>get lamp</li> <li>drawing a map is neccessity</li> <li>downloading the map when stuck is not a shame</li> <li>drop items in maze to find your way out</li> <li>use <em>up, down, SE, SW, NE, NW</em> directions (in maze) too</li> <li>thief is son of a bitch, play dirty because he will</li> </ul> There are two other text adventures I've heard might be worth looking into, <em>Planetfall</em> and <em>Lurking Horror</em>. But that is a story for next time. Hopefully, a longer and a story... </p> Living Room<br> Your collection of treasures consists of:<br> A bag of coins<br> A painting<br> A chalice<br> A jewel-encrusted egg<br> >Score<br> Your score would be 115 (total of 350 points), in 352 moves.<br> This score gives you the rank of Junior Adventurer.<br> <br> <hr> <em> <p> * Well-spread trivia says that "zork" was a jargon word for unfinished software at MIT back in the 1970s. So we could say that Sheldon played a "zork of the Zork". However, I could not find any source to back this up. ESR's <a href="https://www.catb.org/~esr/jargon/html/go01.html">jargon file</a> knows the keyword "zork" only as the game and the most quoted source, <a href="https://archive.org/stream/infocom-paper-2000-12-15/infocom-paper_djvu.txt">Down From the Top of Its Game: The Story of Infocom, Inc.</a> does not contain this information either. If you happen to know a relevant source that could prove this historical trivia, please reach me via <a href="mailto:email@dpolakovic.space">email</a>. </p> </em> <br> </main> <!-- footer --> <footer class="footer"> Copyright 2023 David Polakovic - This publication is licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>. <br> This site is javascript and cookie free. The source code is available <a href="https://git.dpolakovic.space/?p=my-website;a=tree">here</a> under <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">GPLv3 license</a>. </footer> <br><br> </body> </html>
+ ]]></content:encoded>
</item>
<item>
<link>https://www.dpolakovic.space/blogs/free-software</link>
<description>Does your synthetic colleague pose a threat to you?</description>
<pubDate>Tue, 25 Jul 2023 20:00:00 GMT</pubDate>
+ <author>David Polakovic</author>
<image>https://www.dpolakovic.space/blogs/pics/free2.jpg</image>
<pos>100% 0</pos>
+ <content:encoded><![CDATA[
+ <img src="https://dpolakovic.space/blogs/pics/free2.jpg" alt="Ash from Alien (1979)"> </p> <p> A spaceship silently floats in space. There are eight passengers on board, one of which is a monster, hidden from the others. When the monster kills the first passenger, five remaining crew members try to kill the monster but one tries to secretly keep it alive. This passenger is Ash and he is a Čapek-style robot, programmed to help other passengers fulfill their jobs and duties on board. He is also programmed to do other tasks like protect anything with high value to the company that made him. For example, a specimen of the first alien organism – the monster. Unknown to his crew mates, their lives, sadly, have less value than his secret mission. This is the plot of a 1979 movie Alien. Nowadays, while extraterrestrials are still science fiction, universal machines and evil tech corporations are not. </p> <p> So how can you know if your computer or Hyperdyne Systems 120-A/2 series robot isn't plotting some evil schemes against you? <em>Simply</em>, look into its source code. Everything a machine can, and will do, is written there. Problem is that overwhelming majority of software has inaccessible source code. This is nasty trick programmers use to prevent users from reading and copying theirs code. (I will not comment on copying the software as it might lead to talks about so called "piracy"[*], which isn't topic I want to explore here.) But when the source code is hidden it also creates situation where you, as a user, might not benefit from the software as much as the author does. Like when <em>same versions</em> of your favorite spreadsheet editor are distributed differently with <a href="https://answers.microsoft.com/en-us/msoffice/forum/all/my-excel-2016-missing-the-ifs-function/535af21d-456e-4305-a72b-7986211aeab1"> functionality locked</a> behind a paywall. Or when a manufacturer decides what <a href="https://archive.nytimes.com/pogue.blogs.nytimes.com/2009/07/17/some-e-books-are-more-equal-than-others/">files</a> you can have on <em>your own</em> device. </p> <em> <p> (Dis)honorable mentions include software called SoftRAM, which during Win3.X and 9X era claimed that can double your memory without physical upgrade. </p> </em> <p> Luckily, there are programs with open source code, so the author has less possibilities how to make your life miserable. Open Source programs have their code published to be read and edited as you see fit, so you are always able to see, what is going on inside the program and you can change it if you don't like it. Even though there are <a href="https://vscodium.com/#why-does-this-exist"> some traps in open source</a> too, it is great step forward. The problem raises again when advantage is taken of this superior development model by (legally) copying open source program and then <em>closing</em> the source code and circle of unfairness as well. This way, it is very likely that next robot which will try to sacrifice you to an alien monster, will be based on open source software with secret directives distributed inside the unreadable binary file. </p> <p> But there is a solution. Free software - not to be confused with freeware - is basically open source software with license which grants you, <em>the user</em> freedom to use it, share it and modify it any way you want or need. Good Free software licenses prevents anybody from close-sourcing the program. These licenses are called strong copyleft licenses. There are weak licenses too, but they <a href="https://lukesmith.xyz/articles/why-i-use-the-gpl-and-not-cuck-licenses/"> should not be considered free licenses</a> as they miss the point of guarantiing the mentioned rights to user, making them just slightly better variants of open source. If you release you software under real free software license (like <a href="https://www.gnu.org/licenses/gpl-3.0.en.html"> GPL</a>) it stays free forever and every derivative work of it as well. Most notable free software include, of course, Linux kernel and GNU - the system running on top of it. </p> <p> However, running exclusively free software is not easy and open source too for that matter. Every GNU/Linux distribution follows its own ethical vision of what exactly the "free" part of free software means. They differ mostly in classification of codecs and firmware microcode. When you go to one level deeper, you hit the non-free Bios wall. All motherboards manufactured after year 2011 have some kind of <a href="https://en.wikipedia.org/wiki/Intel_Management_Engine">back door</a> build into them. Sure, there is <a href="https://libreboot.org/">free boot software</a> available, but not for every motherboard. To be more specific, the number of <a href="https://libreboot.org/docs/hardware/#supported-hardware">motherboards compatible</a> is lower than number of all of your digits. So in order to be fully in control of your machine, you need to get hardware compatible with this level of user control. This can be often difficult financially or practically, as most of the compatible hardware is often old. </p> <p> And even if you could run the some version of <a href="https://tails.net/">Tails OS</a> on your 120-A/2 series robot, completely bypassing any hardware catches, you still haven't read the 15 million+ lines of code in your free kernel alone. So as with everything in life, even free software boils down into putting some level of trust to the author. You will have to find the correct ratio of free and every other kind of software to use. It is only natural that this ratio will be different for every individual, but as the line between safety and security gets ever more thinner, I would recommend going through the hassle of learning few new habbits and sticking with free/open tools as much as possible. And in the end, it is much easier to trust something you can see into. </p> <br> <hr> <em> <p> * In context of illegal copying of programs, it is hard for me to compare copying of fungible software tools to act of violent theft of non-fungible goods (on the sea). However, I see somewhat relevant use of this comparision in cases of illegal copying of creative works like art. To what one considers to be an art is also for a much longer discussion. </p> <p> But in general, I consider talks about legality of copying any digital file pretty much irrelevant since the Web was built on the idea of copying, which is on itself pretty weird as the existence of multiple copies of the same file on a network is not a good design. </p> <p> There were other propositions for how to design "internet-like network" without possibility of copying files on (or through) it, with the most well known example being the Project Xanadu. I wonder why isn't every giant copyright holder investing their endless pits of money into this long abandoned concept when they are so convinced about righteousness of distribution restrictions over the network. (Maybe because it isn't a good idea.)<br><br> </p> </em>
+ ]]></content:encoded>
</item>
</channel>