Various technical articles, IT-related tutorials, software information, and development journals
Wednesday, July 31, 2013
Why Registry Cleaners Are Useless
Registry cleaners are more trouble than they're worth. This is mainly for one reason: The Registry is only accessed sequentially by registry cleaners. All other applications access individual keys/values through the Windows API, which uses an indexed tree to quickly locate information. The only apps you're speeding up by using a Registry cleaner are Registry cleaners. Also, it should not be the job of any one application to determine what Registry information is or is not important. Destroying empty keys is a bad idea because some application might purposefully create such things to store a hierarchy. Destroying references to nonexistent files is a bad idea because some application might be storing that information as an indicator of the next file to create. The companies that publish cleaners like this spread misinformation about systems needing to be cleaned up when it is in fact the cleaners that cause Registry-related instability in the first place.
Tuesday, July 30, 2013
YouTube Re-entry Time (Also, "How to Fix Your Snowball")
Something I did today made my Blue Snowball compatible with Windows 8! If you are experiencing a Code 10 with your Snowball, here are some things to try:
- Reboot the computer. Seriously, sometimes Windows needs to do something with its drivers that is only possible at start-up.
- Ensure that the USB plug that goes in the microphone has the USB symbol on top. It is possible to insert the cable incorrectly into the Snowball. (Guess how I learned that bit of trivia.)
- Plug the other end of the USB cable into its own USB Root Hub on the computer. Blue states that Snowball microphones draw so much power that they need their own hub.
- If you see an Unknown Device in Device Manager, uninstall its driver and "Scan for hardware changes." A restart may be required after a driver uninstall.
- Download and install all Windows updates, including optional ones. Windows Update can be accessed in Windows 8 under the Metro Control Panel.
- Run "Update driver" on any microphone in Device Manager. A device is considered a microphone if it contains an Audio Endpoint. If the driver installation takes more than ten minutes, cancel it with Task Manager despite warnings. It is likely that the installation has hung after succeeding.
Since I now have a professional-grade microphone, I will be able to easily record Minecraft again. One of my friends has Fraps and is allowing me to share the license, an activity which is allowed for co-op partners.
Sunday, July 28, 2013
.NET - Accessing Windows Forms Controls Across Threads
Windows Forms controls have the irksome property of being thread-unsafe. Microsoft has an article on changing control properties across threads, but it is very complicated. I believe I can do a better job of explaining how to do this.
First, you'll need a subroutine to actually interact with the control. This subroutine will always execute on the form's thread. Once you have that routine, declare a delegate that has the same arguments as the sub. Perhaps an example would make this clearer:
Sub ProcessPacket(Packet As Packet6UserList)
'code that accesses Windows Forms controls
End Sub
Delegate Sub ProcessPacketCallback(Packet As Packet6UserList)
On the non-GUI thread, create an instance of the delegate that points to your subroutine:
Dim ppc As New ProcessPacketCallback(AddressOf ProcessPacket)
Simply invoke that callback on the form to execute it in a thread-safe manner! Parameters to the function are passed to Invoke after the delegate instance in an array.
Me.Invoke(ppc, {Packet})
.NET - Build Files into Executables
Visual Studio has a really awesome feature that can bundle files into compiled programs. Those files can be accessed in code in the form of an UnmanagedMemoryStream or via a more specific resource descriptor. To do so, add the file to the project and set its build action to "embedded resource." The files can be found in the My.Resources namespace and read with a StreamReader. For some file types, like images, there exist classes to automatically create an instance of the appropriate type.
Friday, July 26, 2013
Release "Release" Binaries!
Most IDEs output two different versions of the program when compiling, usually called something like "Debug" and "Release." Almost always, these two versions will run identically. However, you should notice that the binaries in the Debug folder are about 12KB larger. This extra space is taken up by code that allows your IDE to hook into the running program and poke around with variables, usually for debugging/analysis purposes. Besides wasting 12 perfectly good kilobytes, those hooks could allow someone to force the program into a state that it is not designed to handle. Debug versions also tend to contain parts of your code in string format. To hold onto your intellectual property, you should be careful to only distribute the Release binaries.
Wednesday, July 24, 2013
NetBLAM - The First Interaction
NetBLAM is coming along very nicely now that my summer classes (no pun intended) are over. Today, I made the server and client actually talk to each other. It took a few hours to get the network connections to work -- who decided to have AutoFlush off by default? -- but once I could actually keep a connection alive, I was able to find and slay a whole legion of bugs. After connecting to the server, the client is presented with a Server Lobby form that downloads a list of in-progress games after telling the server about the client's name. Since the networking threads are separate from the UI/main thread, I took a crash course (a.k.a. quickly did a Google search) on delegates and callbacks. After some reflecty and delegaty stuff, NetBLAM can understand packets.
On integrated servers, only one game is ever available. |
Tuesday, July 23, 2013
NetBLAM - Starting the Client
I decided on a packet-based system for NetBLAM's communication, similar to that used in Minecraft. The code I use to deserialize the different Packet subclasses is a little weird. Basically, I have an array that maps numbers to classes. Then, once I have the ID of a text than represents some type of Packet, I do this on it:
Packet.PacketClass(PACKET ID).GetMethod("FromText", _
Reflection.BindingFlags.Static).Invoke(Nothing, {SERIALIZED TEXT})
Since the FromText function is static, I don't need to have an instance of the class with which to invoke the method. To be honest, this code has never run, so I'm not actually sure if it works. It should, though.
After defining some packets today, I created the client interface's start-up screen. (I would put up a screenshot if I had finished making it look nice.) It can create an integrated server and it has all the controls necessary to connect to a server, though I might eventually figure out how to implement a server list. The packets so far will be used in the initial "handshake" to determine player and server information.
Packet.PacketClass(PACKET ID).GetMethod("FromText", _
Reflection.BindingFlags.Static).Invoke(Nothing, {SERIALIZED TEXT})
Since the FromText function is static, I don't need to have an instance of the class with which to invoke the method. To be honest, this code has never run, so I'm not actually sure if it works. It should, though.
After defining some packets today, I created the client interface's start-up screen. (I would put up a screenshot if I had finished making it look nice.) It can create an integrated server and it has all the controls necessary to connect to a server, though I might eventually figure out how to implement a server list. The packets so far will be used in the initial "handshake" to determine player and server information.
Sunday, July 21, 2013
NetBLAM - The Integrator
I think I've figured out how I'm going to handle situations that require a player to do something out of turn (like dodging a bullet or drinking a beer before death). I'm going to call a method of the Game class that causes the server to pause the normal turn and get ready for the other player(s) to play a card. Logic.Game won't have to do anything there -- it's abstract -- but Integrator.ServerGame will actually tell the players what is happening.
Speaking of the Integrator layer, I started setting up some classes for the server. I created PlayerCon (a representation of a player's connection that contains network instances and player info) and Server (a factory for actual asynchronous server listening threads). Since the server will run on a separate thread, I can just run a loop forever. Once I have network code, I can start writing and debugging some basic game logic.
Speaking of the Integrator layer, I started setting up some classes for the server. I created PlayerCon (a representation of a player's connection that contains network instances and player info) and Server (a factory for actual asynchronous server listening threads). Since the server will run on a separate thread, I can just run a loop forever. Once I have network code, I can start writing and debugging some basic game logic.
Friday, July 19, 2013
NetBLAM - More Classes, More Problems
I started on the inventory aspect of NetBLAM today by creating a few more classes in the Logic namespace. I also created an abstract Game class that will be used as a hook to some methods that require attention from the server (Integrator) level. The GetStuffByInv methods have been expanded from no-ops into actually functional methods and Player instances have been given access to the Game instance in which they exist. With the player inventory system in place, I can soon implement the characters whose special abilities deal with cards and drawing. There is an issue I have encountered with Bang!'s mechanic in which an attacked player can choose whether or not to dodge the attack by playing a Missed card. I do not know how I am going to have the server pause the attacker's turn and allow the attacked to reply with the appropriate card. I could have the server automatically play the Missed card if possible, but I want to stay as true to the original game as possible. This problem will also present itself with the playing of Bang cards after an Indians.
Rules of Bang! can be located here.
Rules of Bang! can be located here.
Thursday, July 18, 2013
NetBLAM - Development Begins
Since all I can do for ENG 101 is wait for the first draft of my final paper to be evaluated, I started working on a project I've been thinking about for a while: an adaptation of the Italian table game Bang! My adaptation, NetBLAM will be a computerized, network multiplayer version of that. I'd like to be as faithful to the original as possible, but some of the rules are kind of complicated.
So, I fired up my fancy Pro edition of Visual Studio 2012 and created the most advanced project setup I have used to date. It's a multi-project solution that is designed to minimize the number of DLLs each part of the architecture has to reference. So far, I created skeletons for the client (a Windows Forms application), a server (class library), and the business logic (another class library). I'd like to have both an integrated (in-client) server and a more industrial-grade dedicated server be possible using the same code. NetBLAM Client will use the NetBLAM Integrator and NetBLAM Logic libraries. NetBLAM Integrator, the server library, will use NetBLAM Logic.
I started today by attacking the lowest tier, Logic. To implement the characters' special abilities, I have set up a system in which each Character instance has a mapping of events to CharacterEventHandler instances that will apply the character's special abilities. I have created a wrapper of the Character class, Player, that holds information about the character's status in the game, like health and held cards.
Maybe I'm getting a little too enterprisey, but I think developing this project is going to be fun. I'll keep you all posted on my progress.
So, I fired up my fancy Pro edition of Visual Studio 2012 and created the most advanced project setup I have used to date. It's a multi-project solution that is designed to minimize the number of DLLs each part of the architecture has to reference. So far, I created skeletons for the client (a Windows Forms application), a server (class library), and the business logic (another class library). I'd like to have both an integrated (in-client) server and a more industrial-grade dedicated server be possible using the same code. NetBLAM Client will use the NetBLAM Integrator and NetBLAM Logic libraries. NetBLAM Integrator, the server library, will use NetBLAM Logic.
I started today by attacking the lowest tier, Logic. To implement the characters' special abilities, I have set up a system in which each Character instance has a mapping of events to CharacterEventHandler instances that will apply the character's special abilities. I have created a wrapper of the Character class, Player, that holds information about the character's status in the game, like health and held cards.
Maybe I'm getting a little too enterprisey, but I think developing this project is going to be fun. I'll keep you all posted on my progress.
Tuesday, July 16, 2013
FTB: Random Junk Factory
In my (little amount) of free time today, I constructed a factory in FTB that outputs essentially useless stuff (like from a scrapbox). Basically, it feeds massive amounts of cobblestone from Igneous Extruders into Recyclers which produce scrap. The scrap is then packaged into scrapboxes which are unpacked by a dispenser and sorted in a series of diamond pipes. I know RedPower pipes can do this automatically, but I need to use my insane amount of diamonds (from the Wither Skeleton grinder) for something.
It cost a lot of iron (more than two stacks) and wood (more logs than I care to ever see again) in addition to a few diamonds (20). I should mention that I fed all scrap back into the autocrafter -- silly GregTech "rebalancing" making scrapboxes create scrap most of the time. I don't think this setup will ever pay back the materials I used to make it, but it's definitely fun to run down the Hall of Miscellaneous Junk.
The Recyclers and Igneous Extruders (12) each |
Transposers and a timer to pull the scrap out |
The packager (autocrafter) and the unpacker (dispenser and obsidian pipe) |
Storage line with about 40 barrels |
Monday, July 15, 2013
Create API by Loading DLLs at Runtime
Creating a plugin API can be difficult, especially if you don't know where to start. I think the easiest way to do it is to iterate through DLL files in a plugins folder and load them dynamically. Start by creating a class library that defines what a plugin will look like (probably with interfaces). Distribute this library to potential plugin developers and reference it in your application. Get an instance of each plugin by doing this for each file in your plugins directory (for C#, but Java probably has an equivalent):
Assembly assembly = Assembly.LoadFrom(plugindir + file + ".dll");
Type type = assembly.GetType(file);
Object pluginInstance = Activator.CreateInstance(type);
Cast pluginInstance to an implementer of your plugin interface. Once you have loaded all the plugins, you can call some method on each one every time some modifiable behavior starts to execute. I recommend something similar to Forge's event bus.
Also, cactus cat.
Assembly assembly = Assembly.LoadFrom(plugindir + file + ".dll");
Type type = assembly.GetType(file);
Object pluginInstance = Activator.CreateInstance(type);
Cast pluginInstance to an implementer of your plugin interface. Once you have loaded all the plugins, you can call some method on each one every time some modifiable behavior starts to execute. I recommend something similar to Forge's event bus.
Also, cactus cat.
Sunday, July 14, 2013
Use Interfaces Judicously
I have seen interfaces (you know, those abstract class-like things whose names always begin with an I) used for all sorts of strange stuff and I would like to share some of the things I gained from that experience.
Basically, an interface is a great way to ensure that every class that implements it will have certain properties like a collection of public methods. When declaring an interface, no functionality is actually created. Classes that implement an interface have to figure out how to actually make it work -- implement it -- on their own.
Some interfaces are more useful than others. IComparable allows any class to make sure it can be compared with the normal comparison operators. ISerializable, on the other hand, is used more like a flag/annotation. No methods actually have to be defined; the serializer just checks to see if you want this class serialized. It's really pointless to cause a future programmer worry over a possible change to the interface that might blow everything up instead of just registering a simple annotation.
Before making an interface, think about whether an abstract class -- or even just a normal class -- could do the job. (Also, please never make an interface that is intended to be implemented by exactly one class. I'm looking at you, Skype.) A good use of an interface is to allow somebody to extend some subclass of the TileEntity class and also be an IInventory. A bad use is to create an IChunkProvider when you already have an abstract ChunkProvider class. Remember, the purpose of interfaces is to allow inheritance from multiple abstract classes.
There's sometimes some gray area on whether an interface or a common superclass should be used. For example, it might be nice to have IRenderableEntity that defines a draw(Canvas) method. There might be totally separate types of renderables such as ParticleFX and PieceHostile. However, it might be simpler to have both those types extend some abstract GameObject class.
Moral of the story: Try not to go crazy with interfaces. I know it's enterprisey and fun to set up, but requiring excessive implementation will cause pain in the future. Think of the developers you might bring on in the future.
Basically, an interface is a great way to ensure that every class that implements it will have certain properties like a collection of public methods. When declaring an interface, no functionality is actually created. Classes that implement an interface have to figure out how to actually make it work -- implement it -- on their own.
Some interfaces are more useful than others. IComparable allows any class to make sure it can be compared with the normal comparison operators. ISerializable, on the other hand, is used more like a flag/annotation. No methods actually have to be defined; the serializer just checks to see if you want this class serialized. It's really pointless to cause a future programmer worry over a possible change to the interface that might blow everything up instead of just registering a simple annotation.
Before making an interface, think about whether an abstract class -- or even just a normal class -- could do the job. (Also, please never make an interface that is intended to be implemented by exactly one class. I'm looking at you, Skype.) A good use of an interface is to allow somebody to extend some subclass of the TileEntity class and also be an IInventory. A bad use is to create an IChunkProvider when you already have an abstract ChunkProvider class. Remember, the purpose of interfaces is to allow inheritance from multiple abstract classes.
There's sometimes some gray area on whether an interface or a common superclass should be used. For example, it might be nice to have IRenderableEntity that defines a draw(Canvas) method. There might be totally separate types of renderables such as ParticleFX and PieceHostile. However, it might be simpler to have both those types extend some abstract GameObject class.
Moral of the story: Try not to go crazy with interfaces. I know it's enterprisey and fun to set up, but requiring excessive implementation will cause pain in the future. Think of the developers you might bring on in the future.
The Y2K Problem
I'm not sure if this has already been explained somewhere else, but I'll explain it again anyway. Basically, people thought Y2K was going to wreak massive havoc because most computers stored years in two-digit form. People thought all kinds of explosions would happen when "100" tried to occupy a two-digit space. I am writing this article to give a calm look at what problems could have occurred.
First, and obviously, "100" is more than two digits. I'm guessing most systems would have either kept the first two ("10") or the last two ("00"). This would have resulted in some noodliness with date comparisons, but nothing world-ending. There might have been slightly more serious issues in business applications that recorded trends over continuous periods of time.
A rare problem case involves a hypothetical application that uses an unsigned byte two-digit year as an array index. Frequently when using arrays, one must access the previous element (n - 1). Doing so for year 00 would attempt to access array index -1, which was always a fatal error for the systems of that time. Such an application would crash hard when the century turned, possibly corrupting data but not causing all nuclear warheads to spontaneously launch.
The last situation I can think of is a punch card reader (maybe kind of like the ones that read your ACT bubbles) that has two columns of digits for the year. People (especially very old people) would have a bad time recording their date of birth. The machine might also think the writer means 19nn and there would be no way to determine which century the year belongs to. This was remedied very easily by adding an adjacent true-false bubble for "is 21st century?"
So, there really was no danger of appalling disaster as a result of computers' misunderstanding of the new century. I'm not sure how the rumor got started, but it was definitely told melodramatically.
First, and obviously, "100" is more than two digits. I'm guessing most systems would have either kept the first two ("10") or the last two ("00"). This would have resulted in some noodliness with date comparisons, but nothing world-ending. There might have been slightly more serious issues in business applications that recorded trends over continuous periods of time.
A rare problem case involves a hypothetical application that uses an unsigned byte two-digit year as an array index. Frequently when using arrays, one must access the previous element (n - 1). Doing so for year 00 would attempt to access array index -1, which was always a fatal error for the systems of that time. Such an application would crash hard when the century turned, possibly corrupting data but not causing all nuclear warheads to spontaneously launch.
The last situation I can think of is a punch card reader (maybe kind of like the ones that read your ACT bubbles) that has two columns of digits for the year. People (especially very old people) would have a bad time recording their date of birth. The machine might also think the writer means 19nn and there would be no way to determine which century the year belongs to. This was remedied very easily by adding an adjacent true-false bubble for "is 21st century?"
So, there really was no danger of appalling disaster as a result of computers' misunderstanding of the new century. I'm not sure how the rumor got started, but it was definitely told melodramatically.
Wednesday, July 10, 2013
Kickoff Poetry
Welcome to Fleex's Lab! I just split from Ben's Blitz Blog and I am ready to do some technical articles! First, we have a kickoff to do. How about a pathetic attempt at poetry?
Perfect! Alright, here's a piece called "Deliberation on Types" I started writing today. Basically, I think about Java/.NET classes and compare them to types in the real world. It's not finished, and it can barely be considered poetry, but here we go:
Perfect! Alright, here's a piece called "Deliberation on Types" I started writing today. Basically, I think about Java/.NET classes and compare them to types in the real world. It's not finished, and it can barely be considered poetry, but here we go:
Yes, the world has many things
But more importantly, these things have many types
Things in some types are all things in another
Some types just cannot be compared
Schoolchildren know all squares are rectangles
And most understand how only some rectangles are
squares
Utilitarianism says everything can be described by
"utility"
And utility is all we need to measure
Forget about your shapes and standards and consider
The apple and orange and their use in
A common complaint about comparisons
But they're both fruits
Think less specifically about complex types
Instead, about what they are both
Two different fruits are still fruits
"Fruit" is not an abstract concept
All members of a class have a common property set
When one gets over the distinctions
One sees attributes that apply to all
And goes on to judge based on those
Apples and oranges can be compared
When their types are less distinct
So why do we all not compare everything
By thinking of each as a concept
Maybe everything can be just an idea
But it must retain some properties
Or else its change was meaningless
Without common data, no comparator can read
And that's where it ends currently. I need to add stuff about null/Nothing, but I think I've made poetry appreciators sad enough for now. Look forward to cool stuff here at Fleex's Lab!
Quick note on that poem: I plan on using the final product as a submission in an online class I'm taking. If you are the professor of said class and have received the above as a submission, please send a message to either this Blogger/Google account or the Canvas account of your student asking him to identify as the other. Thanks for enduring my poetry!
Subscribe to:
Posts (Atom)