Friday, November 29, 2013

FTB Unleashed - Tinker's Construct Smelting, Casts, and Patterns

Tinker's Construct is a remarkably well documented mod compared to most Minecraft mods, especially those in FTB. In fact, it even gives you pretty awesome in-game manuals. However, it took me forever to figure out what you actually have to do to get making custom tools.

As you probably gathered from the first in-game book, you need some workshop blocks. However, what you might not have understood is that, to start out, you just need a Stencil Table, Part Builder, and Tool Station. They're all just wood. Make a couple of spare blank patterns as well.

Shove a blank pattern in the Stencil Table and click Next and/or Previous until you find a fragment that looks useful (I recommend pickaxe head). Take it out. Shove that into a square slot in the Part Builder and some wood or cobble in the ingot-like slot. Take the new piece out. This does not work with metals. For metal, you need a Smeltery. You can do similar things using just this set-up to make pretty lame composite tools if you figure out the Tool Station. In the Tool Station, you click the type of tool you want to make on the left and then put in the components in the slots which will appear.

However, I think it's pretty easy to advance to the next stage: smelting. Gather a whole bunch of clay, sand, and gravel. Combine it into grout and smelt that into Seared Bricks. Create exactly 18 Seared Brick blocks, 1 Smeltery Controller, 1 Seared Tank, 1 Seared Faucet, 1 Smeltery Drain, and 1 Casting Table. Put a 3x3 square of the Seared Brick blocks on the ground to start. Then, up one level and not directly above the bricks, place the Controller, Tank, and Drain facing in. Complete a ring around the outside (corners unnecessary) with the rest of the bricks. Attach the Faucet to the outside of the Drain and place the Casting Table directly underneath it.

Once that's all done, grab a bucket of lava and use it on the Tank. It should light up the Controller as well. You now have a functional Smeltery! Now, find those tool parts you made earlier and right-click the Casting Table with one. It should insert itself. Pop in 2 gold ingots or 1 ore into the Controller and let it melt. Right-click the Faucet and the liquid should pour into the Table. If you've set things up correctly, it will cool after three seconds, producing a solid cast around the part. Pop both of them out, and you have a cast! I'm fairly certain you can just throw out the cheap part.

Now, it's time to make a part with metal. If your Smeltery still had liquid metal in it, break and replace the Controller. Casts must be filled with a different material than was used to make them. Put in metal of your choice (I did iron the first time). Pop the cast back into the Casting Table and, once the metal is liquid, right-click the Faucet. If it doesn't cool into the part after a few seconds, put in more metal. Once solid, pop both of them out and you have a metal part!

Once you've made enough parts for a tool, put them together in the Tool Station. You can also modify them there by adding unusual substances found in the second book you got.

Wednesday, November 27, 2013

Creating Extension Methods in VB .NET

An "extension method" is a method of a class or interface that is actually defined in a different module, usually by a different author. They are usually used to "extend" the functionality of existing types without creating new ones.

In C#, creating extension methods is pretty easy. Simply put a "this" before the type on the first argument, which indicates that it is the instance on which the method is running. In VB, it's slightly different but still pretty simple. First, import System.Runtime.CompilerServices at the top of the file containing the module. Then, apply the <Extension> attribute to the Sub or Function. When writing the method body, write as if the first argument is the current object. It obviously has to be the same type as the type to which you'd like to apply the extension.

Here's one I like to add to the string type:

Imports System.Runtime.CompilerServices

Module Extensions
 <Extension> Public Function EqCaseless(This As String, _
  Other As String) As Boolean
  Return String.Equals(This, Other, _
   StringComparison.InvariantCultureIgnoreCase)
 End Sub
End Module

Then, I can compare strings caselessly like this:

If input.EqCaseless("splosions") Then End

Tuesday, November 26, 2013

Fixing SupaChat

A couple of years ago, I wrote a chat server called SupaChat Server and a lightweight client for it. A project I did for World Literature - a Beowulf text-based RPG as a SupaChat Server snap-in - reminded me of it. Like I wrote a few weeks ago, it's really not that bad. However, it has a major problem. Instead of multithreading it myself, I just had timers in the main form that triggered read and ping events. While it was pinging all the clients and actually waiting for a reply, no messages would be processed. That caused all manner of ping timeout disconnections (especially because it happened every three seconds) in my presentation. I then decided that I should refactor it to resolve those problems. It'll take a lot of rewriting to implement a proper threading and queue system, but the server should run a lot better.

Monday, November 25, 2013

Tour of Interesting Registry Places, Part II

Open up your Registry Editor or registry inspector of your choice and check out these cool places in Windows! All of these things start in \HKCU\Software\Microsoft\Windows\CurrentVersion
  • \AccountPicture points to, obviously, your account picture, but also your name. Your name doesn't have to be the same as the name of your Microsoft account. Those parts are stored in FirstName and LastName, both of which will be overridden if DisplayName is not blank.
  • \Authentication\LogonUI\Notifications\Badge contains one folder for each application that can display a notification on the lock screen. There are keys for the version, rank in the list, and what looks like a COM+ package descriptor.
  • \Explorer\Advanced has settings for Windows Explorer that aren't usually accessible. Most of them seem to be Booleans, but there are some that take integers, all as a REG_DWORD. Notable are DontPrettyPath, IconsOnly, ServerAdminUI, and ShowInfoTip.
  • \Explorer\BitBucket\Volume\ keeps the Recycle Bin settings for your drives, each of which gets its own folder. Each folder contains MaxCapacity, the number of megabytes your RB can hold, and NukeOnDelete, which specifies whether or not to permadelete all the time.
  • \Explorer\FileExts, which might be the target of HKCR, manages the "Open With" list for each file extension. It can contain the folders OpenWithList and OpenWithProgids for each extension. In OpenWithList, MRUList is a list of characters, the key named by each of which contains one entry. OpenWithProgids contains the friendly name of the file type.
  • \Explorer\Ribbon contains QatItems, an XML string stored as a REG_BINARY. It appears to be where the Explorer ribbon loads its items from.
  • \Explorer\RunMRU lists the autocomplete items in the Run box, stored in a manner similar to that of OpenWithList under FileExts.
  • \Policies\Explorer has a single entry, NoDriveTypeAutoRun. I'm fairly certain it will switch off auto-run for all removable drives, a wise security measure.

Sunday, November 24, 2013

Tour of Interesting Registry Places, Part I

The Windows Registry was an idea that looked really good on paper and is moderately decent in practice. Over the years, it has become a convoluted place full of no-ops, interesting structures, settings that you can't find anywhere else, and a whole lot of confusing keys. I did a little poking around there today and discovered that it is pretty awesome just to see what you can do there. Let's do a tour!

All you need is a copy of Windows! Even a fresh install should have the structure and a lot of stuff in place. To begin our tour, launch the Registry Editor by typing "regedit" in the Run box (press Windows+R). If you've had it open before, collapse the open keys to start from the beginning.

  • HKCU\Environment contains your environment variables. An example of these is PATH. You can add REG_SZ values to allow expansion of %pathvariables% in the Address Bar.
  • HKCU\Control Panel\Colors specifies the RGB colors of Windows controls in various states. They are stores as REG_SZ which consist of three numbers (red, green, blue) delimited by spaces. Adding new entries won't do anything.
  • HKCU\Control Panel\Mouse contains settings that are usually configured with the Mouse dialog in Control Panel. However, you can also set the rectangle in which a second click in rapid succession will count as a double click, whether the computer will beep when the mouse is clicked, and some other interesting things I don't know about. Most are numbers stored as REG_SZ.
  • HKCU\Console changes the visual properties of the command prompt. The most interesting entries are the ones beginning with "ColorTable", for they map the QuickBASIC/DOS 16 colors to RGB Windows colors. They are stored as REG_DWORD with only the last six hex digits used. Boolean flags in this folder are also REG_DWORD, simply 0x0 or 0x1.
As I continue exploring, I will write more!

Friday, November 22, 2013

Intro to Boolean Algebra: A PowerPoint

For a book presentation (on Randall Hyde's The Art of Assembly Language), I created a small PowerPoint to give an introduction to Boolean algebra. It requires some talking on stuff that's not actually on the screen, but is that not how presentations are supposed to be? Anyway, it might be useful for a CS class. It starts with the 0/1 closedness and ends with minterms and simplification.

Download Ben Nordick's Intro to Boolean Algebra

Thursday, November 21, 2013

Install IIS on Windows XP without CD

IIS 6.0 is a very solid HTTP server (among a bunch of other Web-related services) that can be run on any Windows XP Pro computer. It's installation is usually pretty simple: Turn it on, put in your Windows install disc, and watch it install. However, you can't do the normal installation without your CD. After a little searching on the web, I have discovered a way by which IIS can be (legally) installed without having to track down that disc.

First, you'll need to download a disc image that contains the necessary files, for example this one for 32-bit SP2 (will work for installing IIS on SP3). Open a command prompt, navigate to the folder containing it and run it with the /extract switch with the destination folder path as an argument. An i386 folder will be created there, which will contain the files necessary to install IIS. Point the snap-in installer to that place and you'll be going!

Wednesday, November 20, 2013

Robotics - Focus Shift

We have determined after our disastrous failure at the first FTC qualifier that we need to change our focus. The block-moving conveyors, while pretty awesome, don't work that well. They require a lot of space and maintenance. However, one major thing makes us want to get rid of them: They don't score very many points at all. The bonuses in this game are so overpowered that actually taking blocks and putting them in the appropriate places is pointless. So, we are just going to have a little shelf-like thing that will dump the block we place on it into the infrared crate in the autonomous period. Even though only a few people were at today's meeting, the redesign has started. It should take only a few weeks to get the fixtures in and maybe another week or two to make them work well. Then, it's all practice and fine-tuning!

Monday, November 18, 2013

.NET - Guide to Server Basics, Part II

Now that you have a listener to catch new connections, it's time to actually communicate with them. I recommend another thread for reading in data. We'll use a queue of messages, but we'll need a new class to keep track of messages.

Public Class QueuedMessage
 Public Received As DateTime
 Public Data As String
 Public Sender As ClientCon
 Public Sub New(R As DateTime, D As String, S as ClientCon)
  Received = R
  Data = D
  Sender = ClientCon
 End Sub
End Class

Now we can make that queue and add data-reading and message-processing loops.

Public ProcessQueue As New List(Of QueuedMessage)
Public Sub ReadData()
 Do
  For Each c In Cons
   Try
    If Not c.Connected Then Exit Try
    Dim s As String = c.Reader.ReadLine()
    Dim msg As New QueuedMessage(Now, s, c)
    If Trim(s) <> "" Then ProcessQueue.Add(msg)
   Catch ex As Exception
   End Try
  Next
 Loop
End Sub
Public Sub ProcessLines()
 Do
  If ProcessQueue.Count > 0 Then
   Dim d As QueuedMessage = ProcessQueue(0)
   'Your handling code here using d
   ProcessQueue.RemoveAt(0)
  End If
 Loop
End Sub

Insert calls to start threads for those loops to the server's initialization sub. For convenience, I recommend having a writing sub in the connection class. Also, soon we'll need a time field to keep track of keep-alives.

Public LastKA As DateTime
Public Sub Send(Data As String)
 Writer.WriteLine(Data)
End Sub

Set the timer and give the client a little head start in the client acceptance code:

c.LastKA = Now.AddSeconds(5)

With that ready, insert a line into the data-reading loop that resets that field when data is received.

c.LastKA = Now

Prepare to enforce the timeout.

Public Sub Discon(Con As ClientCon)
 Con.Client.Close()
 Cons.Remove(Con)
End Sub

Finally, add a check loop sub.

Public Sub CheckKA()
 Do
  For Each c In Cons
   If c.LastKA.AddSeconds(10) < Now Then Discon(c)
  Next
 Loop
End Sub

Just make sure to have the client send updates or useless KA messages once every few seconds. I'm not sure what I'll cover next time.

Sunday, November 17, 2013

.NET - Guide to Server Basics, Part I

It's moderately difficult to create a server application for the first time. This guide should help you establish a listener and an array of connections.

First, you're going to need to import System.Net.Sockets and System.IO. System.Threading is useful if you want a multithreaded listener. I recommend creating a class to hold connection objects.

Class ClientCon
 Public Client As TcpClient
 Public Stream As NetworkStream
 Public Reader As StreamReader
 Public Writer As StreamWriter
End Class
Dim Cons As New List(Of ClientCon)

The collection of connections is helpful to check all the clients in one sweep. Declare a listener as a TcpListener. I usually create a server class to manage all the servery stuff.

Class Server
 Public ShutDown As Boolean
 Public Listen As TcpListener
 Public Sub StartListening(Port As Integer)
  Listen = New TcpListener(IPAddress.Any, Port)
  Listen.Start()
  ThreadPool.QueueUserWorkItem( _
   New WaitCallback(AddressOf Listener))
 End Sub
 Public Sub Listener()
  Do
   If Listen.Pending() Then
    Dim c As New ClientCon
    c.Client = Listen.AcceptTcpClient()
    c.Stream = c.Client.GetStream()
    c.Reader = New StreamReader(c.Stream)
    c.Writer = New StreamWriter(c.Stream)
    c.Writer.AutoFlush = True
    Cons.Add(c)
   End If
  Loop
 End Sub
End Class

Creating a new instance of that class and telling it to start listening will create a new thread that listens for client connections, accepts them, and puts them in the connection list.

Next post, we'll get some communication and keep-alives going.

Saturday, November 16, 2013

Robotics - The Qualifier, Take 1

Today was the first (of two) FTC qualifiers in which my team is enrolled. We woke up around 5 AM to drive for an hour and a half over to Mount Vernon, which contained the hosting school. For the first few hours, all we needed to do was walk around to the inspection stations, where volunteers looked at checklists and made sure our robots didn't have illegal component on them. I expected the software inspection to actually look at the code, but all they did was see that we were using a compatible firmware version on the NXT and that we had used the Program Chooser. Once all the inspections and judge interviews were complete, we walked around the maintenance area to see if other teams needed assistance - "gracious professionalism" as they say.

After a quick set of rules on what is allowed during the stages of tele-op mode, the matches began. Each team competed in six rounds, of which there were in total 36. Each round had two alliances, each composed of two teams, competing to score the most points. The team captain and I were drivers, he controlled mobility and I was at ops.

  1. We got to be in the first round of the day! Our partner didn't have an autonomous, so there were no collisions to worry about. However, when we went to raise the flag in the endgame, the motor simply did not run. I pressed all the buttons near there, including the reverse, but it failed. We lost.
  2. This time, our partner team did have an autonomous. Fortunately, they had an alternate version which didn't take them anywhere near us on the field. Between this and the last match, we made sure the flag raiser was working after recompiling. It worked great... and flew right out. So, we were again unable to raise the flag. It was close, but we lost.
  3. The autonomous situation was similar to that of our second match, which executed perfectly. Well, it actually collided with a member of the other alliance, but it didn't cause a problem. Later in the match, an axle in one of our wheels derailed, rendering us immobile and unable to raise the flag. We lost by a lot.
  4. Finally, we were put with a team that was very prepared. Both autonomous programs executed flawlessly, scoring a total of 80 points. The endgame plan was for us to raise the flag and our partner to pull up onto the bar. With around 40 seconds to go, one of our belts broke, rendering us unable to move blocks. As we approached the flag, that same belt broke into three pieces and fell off the robot, scattering fragments about. A few moments later, our robot tripped on one of those fragments and fell backwards, rendering it immobile. However, in a glorious sequence of events, our partner both raised the flag and performed a pull-up. Our first win was a total disaster!
  5. In this match, we were playing against the other team from our school. They had a great partner, but ours was not so well equipped. Things got even worse when our autonomous failed to execute. The disaster index continued to rise when the Samantha network got clogged, lagging all the robots at least a little but rendering ours uncontrollable. We scored essentially zero points, considering our partner had no autonomous anyway.
  6. After checking our Samantha and NXT connections, we were feeling a little better about our last match. Unfortunately, the controllers that we were supposed to pick up after the autonomous period ended were not placed correctly. So, our alliance's controllers were mixed up, resulting in chaos. Even once we got that sorted out, the lag and the lack of time remaining destroyed our chances. The other alliance won handily.
It was, in summary, a disaster. On the good side, we learned what's going to go on when we actually get serious for the February qualifier. Stay tuned for The Qualifier, Take 2!
During match three. The team captain is to the right of me.

The results as shown on the public display board.

Friday, November 15, 2013

Robotics - Down to the Wire

Similar to what I hear happened last year, we all stayed considerably longer than expected to finish the robot the night before a competition. This year, there were two factors that made it easier: we were all there and tomorrow's event isn't the last one. Tonight, the following things happened:

  • We tried to fix the autonomous program. It never worked particularly well, but it was being especially temperamental tonight. I ended up creating a simplified program that will score fewer points, but is hugely more reliable.
  • We actually got a flag raiser. It does its job, but requires both the driver and operations controller to be very precise about the approach. Despite its motor having emitted smoke for a while, there doesn't seem to be a problem.
  • The Samantha module made things difficult. I had to flash that thing not once, not twice, but three separate times during the meeting to keep the Wi-Fi link alive. Fortunately, at the actual competition, the inspectors will flash the module to their own network.
  • The height was a problem. Apparently, in our rush to make stuff work, we failed to notice that the robot was about a half-inch above the limit. To remedy this, a cam was put together by drilling holes through a place off to the side of the center of a wheel and attached to a motor. It was amazingly useful... until slamming into the guards destroyed the gear box. Our tests, however, demonstrated that we can still get blocks into the baskets.
It's not working as well as we had hoped, but it is working! After this qualifier, we will have a few months to refine our design and hopefully do a lot better the next time!

Thursday, November 14, 2013

Robotics - Autonomous Issues

With the robot's physical properties complete, all we have left to do before the competition on Saturday is to finish the autonomous routine. Despite my existing code being pretty good, what it actually did was pretty miserable. We spent an entire hour trying to get the first stage (drive up to the infrared beacon and dump the block into the container) working without much success. There is a strange bug in the code or intrinsics that causes unpredictable things to happen when both motors are moving backwards. It looks like tomorrow will be a late night.

Wednesday, November 13, 2013

Robotics - Belt Fixed

One of the semi-recent redesigns on the robot had the problem of the belts catching on the support beams below them. Today, we used the Dremel to cut off the portions of metal that were causing the issue. I also finished moving the code into the appropriate template and adjusting the autonomous period program. We're pretty much ready with the robot; we just need to practice driving and get the autonomous timers right.

Tuesday, November 12, 2013

Robotics - Templates and Finalization

I just discovered that, for the robot's code to be acceptable and legal, it needs to be based on templates that FTC gives out with RobotC. I had already made sure my code had the same function as these, but I hadn't actually used them. So, I spent the second half of the meeting copy-pasting code into the appropriate sections of the template. Since I figured the judges might like to read the code easily, I also inserted linebreaks and my own comments (eliding the original 10-line comment blocks that tell me nothing). The build team has the robot almost done, just a little bit of adjustment needs to be made to the belts. Once that's ready, we can start auditioning drivers.

Monday, November 11, 2013

Robotics - Crunch Time

It has just hit us that the FTC qualifier we are entered in is this Saturday: five days away. Our robot is still in a state of uncertainty. The design keeps changing to accommodate new problems, most recently our lack of another motor controller. Essentially, all we really need to get competition-ready is a method of getting the blocks off the ground and into our belt shaft. I'm working on getting the autonomous in a presentable state, which is going reasonably well. It would be going even better if I could test it: A recent redesign left no place for the battery array.

Sunday, November 10, 2013

Looking Back: SupaChat Server

As I develop the snap-in for SupaChat Server I mentioned last post, I'm finding a lot of issues with the software. Let's talk about it!

  • SupaChat Server was started by me in sixth grade after my computers teacher told me to "do something with variables." It grew organically with minimal direction of what I wanted do actually have it do. I had created an incredibly lame "chat" application that worked by writing lines to a shared file before. SCS was my first time actually making networking work.
  • It quickly became a serious effort. After a year or so, it grew into a pretty large thing. I even created a lobby for multiple server instances to meet potential clients in. Obviously, that part never ran, but the code worked.
  • There's no multithreading or queuing. When a new client connects, the server gives it 5 seconds for each auth field and a few more for optional encryption information. During that time, execution is blocking, waiting for the client to respond. Therefore, while connections are being processed, no other information is being relayed.
  • That said, everything worked surprisingly well. All the commands worked and the UI didn't even get too slow.
  • I didn't know about the principle of keeping processing and UI separate. In the data module creatively named "Code", many references are made to things in frmMain, especially to update the user list. However, I do feel kind of proud of that thousand-line file; it got me into Black Hawk College's computer science program in eighth grade.
  • Encryption was an afterthought. SCEC works perfectly fine, and I guess is secure if the attacker didn't hear the beginning, but it relies on people not knowing how the server chooses the key. (Hint: it's based on a very suspicious line in the introduction.)

Saturday, November 9, 2013

The Beowulf SupaChat RPG

For an upcoming creative project on Beowulf (for lit class), I decided to create a text-based RPG featuring events similar to those found in the book. Since network infrastructure and all that stuff is a pain, I am trying to use the service snap-in feature of my old SupaChat Server. It's been three years since I did anything with that; as I look at its code, I see so much that could go horribly wrong, mostly the complete lack of multithreading. So far, the program can connect to an SCS, snap itself in as a service, and come in like a wrecking ball to new groups and adminify itself for RPG handling there.

Friday, November 8, 2013

Robotics - Dremel

Dremels are cool things. They have substitutable parts, are easy to handle, and have a good owner's manual. During an exceptionally length early-out Friday robotics meeting, we used one such device to cut a piece of aluminum. We actually broke at least three of the cutting heads, but it comes with many packages; evidently, breakage is pretty common. That piece was used as the back of our conveyor assembly. Once that was all fixed into place, I did some adjustments and testing to the new two-controller system.

Wednesday, November 6, 2013

Robotics - T-Shirt Time

We're still waiting on drills and other equipment necessary to continue the redesign of the robot, so today's meeting was used to finalize the t-shirts. They're very similar to that of last year's team: an apple and the pi symbol. They're set on a light gray background with the names of all the members on the back. There's just 10 days left before the first state qualifier.

Monday, November 4, 2013

Robotics - Double Controller, So Intense

As an important FTC qualifier draws near and the build team starts totally redoing our design, I'm finally implementing the second controller that is necessary to have good control. The general convention is to have one controller for moving the robot and use the other for operations. All I had to do is move the code for controlling the conveyor belts to the variables for the new controller. Since I didn't have much to do while the build team dismantled the robot, I created a new mode of controlling the conveyors using the top hat.

Sunday, November 3, 2013

Robotics - Autonomous Testing

The autonomous period development is going reasonably well. The robot can use the infrared sensor without special drivers, which I was unable to install correctly. However, it can still sense the general direction of the beacon perfectly fine. We have been using that to start our autonomous programming. So far, the robot can find where the beacon is, turn, and then make a decent attempt at driving up to the pendulum. At that last step, it gets a little confused due to my slightly indiscriminate handling of direction. It also has issues turning such that the sensor (which is mounted on the side of the robot for drive-by scanning (very gangster)) is perpendicular to the beacon. We expect most of these problems to be resolved when we actually get a real field installed in our testing lab. In related news, the conveyor belt has had all the rubber inserts installed and can pick up blocks with success.

Friday, November 1, 2013

Logofrag - Adding Frags

Well, I modulized a little bit more functionality used by the thread view of Logofrag. I scrapped the idea of having the user write one word in each text box and select both sides' punctuation for adding a frag. Instead, I'm going to let the entrants write freely and then press a "preview" button that will make sure no illegal characters are being used, check that the frag meets the length requirements, and figure out what is punctuation and what isn't. Once the user makes sure that Logofrag didn't destroy the formatting in the verification, the newly made visible Submit button is used to actually add the fragment. Also, I discovered that it might be easier for me to keep a User object in the Session instead of an ID; it's slightly annoying to have to constantly query the database to get a user's actual information.