Wednesday, February 08, 2006

Games with balls

What is it with games with balls?

Games with balls simply marble^Wrock.

Thursday, January 26, 2006

LBA3 Campaign

One of my all time favorite games is Little Big Adventure. The first game in the series was released in 1994, a sequel was released in 1997. The team behind it also planned for a 3rd release, but things didn't went as they hoped to. A lot of things happened, the team moved to various companies, split up, etc. The posibilities for an LBA3 were quite slim, even tho the whole team wanted to make the game.

But recent developements gave new light to the posibility of LBA3. This got the fans from the Magicball Network excited. They have started a campaign to put LBA in the spotlight to give LBA3 a higher chance to be picked up by a developer.

On a side node: Sebastien Vianny showed some activity on the LBAwin project again, version 0.8.1 might be close. I hope this will be a steady walk to a final release.

Saturday, November 12, 2005

UnrealAdminWiki

A while ago I finally finished some work on the wiki for the UnrealAdmin page. It's an modified version of the MediaWiki wiki engine (the same one as is used for WikiPedia). One of the more important things I modified was to hook up the user system with our main site that was powered by vBulletin. It's isn't as easy as it looks. Because MediaWiki is quite limited in the username format, only alphanum and _ are allowed. But vBulletin allows pretty much everything. This create a very annoying problem. How to hook up those users. I could imply convert the username to MediaWiki style, but this could create name clashing. So instead I ripped out the whole User namespace support and changed the way usernames where parsed. Username will now foward to the vBulletin profile page for users that exist. Some of the changes required modifing original files (which I don't like). So right now when a user type ~~~ (for a signature) it will be replace with a new tag [[profile:uid|Username]]. The username is ignored in further processing, it's only useful when editing a page and still being able to see the actual username. All links to the user namespace, [[user:Username]], will also be rewritten to an url to the vBulletin profile page (if the username can be found). Now this creates another problem, some usernames can contain characters so that [[user:Username]] doesn't work well. I fixed this by adding some magic: [[User:?|Username]] will work for these usernames and still allow me to look up the actual info.

If you are creating a new site with MediaWiki (or any other wiki) and vBulletin simply limit the characters that people can use to alphanum and the underscore (or space). This will save you a lot of work.

Besides the vbulletin integration I also made a couple of other extentions, pretty much all are available. While working on extentions I found out that MediaWiki doesn't really make it easy to develop extentions. Sometimes you need to change stuff deep inside some routines, or at least on certain places. Then you'll find out there are not enough hooks available to get to the right place. vBulletin 3.5 did it much better. For example simple things as adding ACL for pages isn't possible without modifyin the original code. But then again, MediaWiki is one of the nicer PHP powered wikis I've found so far, and their text syntax is nice too (much like the syntax UnrealWiki uses).

Thursday, September 22, 2005

UsUnit

There you've got it. The second more mature release of the UnrealScript Unit Testing Framework. A few minor changes to the real framework. More important is a working WebAdmin module.

So far UsUnit contains some graceful code, some somehwta hacky code and some scary code. For the webadmin module I tried to create a better PlayInfo to HTML converter that the one that was already present. Actualy, the existing one couldn't be use in arbitrary places. My converter current supports just check and text types, but also arrays. My initial idea was to auto detect arrays, but because of a bug in PlayInfo's validation code for TEXT render types this can't be used. Instead you will have to use a CUSTOM render type which will figure out of it was suppost to be rendered by the TEXT type. For the TEXT type I also made a special case of numeric values. If the extra data contains range information it will be used to show a specialised text filed with a plus and min button and it will respond to certain key events (up, down, home, end, pgup and pgdown) to modify the value.

An other tricky issue I had to solve was to add some logic to cope with possible invalid test classes. The test class configuration uses strings. It might happen that a single entry isn't a valid name for a class. But during configuration I don't want to remove those entries, or change them at all. Therefor I added a displacement array that keeps track of the array index differences between the two arrays.

More information about UsUnit.

Saturday, September 17, 2005

<a href="javascript:..."> rant

Sometimes you want to do some special dynamic stuff on a webpage, by means of javascript. Well apperently a lot of people on this world think that only anchors (you know, thos <a href="..." /> thingies) are the thing for that. Well it's NOT. In fact it's the worst possible thing. Why? well, an anchor should contain a link to a new location. "javascript:..." is not a new location. Besides, since it's already used for dynamic stuff you should just use the "onclick" argument of pretty much every visible HTML tag. And now we ofcourse get: <a href="#" onclick="..." />. Well that's wrong too. Why? because you you create a link to nowhere. People (like me) often open a link in a new window\tab (middle mouse button is some browsers, or ctrl+click). Using a "#" or "javascript:" as link just breaks stuff like this and makes it annoying.

What is the right thing? Well, there are two options:

  1. For complete dynamic things that don't open new pages you should do something like <span onclick="javascriptFunctionCall()" >your text</span>, and maye make it more visible my means of CSS
  2. When you want to open a document in a special way (like a popup window with special properties) do something like this: <a href="linkToTheDocument" onclick="javascriptCallToOpenWindow('linkToTheDocument'); return false;">your text</a>. This way when a user normally clicks on the link it will call that javascript function with the url. If the user clicks on that link with the middle mouse button (or ctrl+click) it will simply open that link in the default behavior of the browser. The "return false" in the onclick makes sure the default behavior doesn't happen in case of the onclick event. This method gives you the best of both worlds and doesn't annoy users that link to middle click or don't have a javascript enabled browser.

UnrealWiki Developer Journal 17-09-2005

It has been a while since my last dev journal entry (again). First a little update about my last entry. I'm no longer actively working on a VisualStudio AddIn. The features I wanted to add required me to write a VisualStudio Package instead of just an AddIn. Writing a package isn't as simple as writing an AddIn. I hit an issue while implementing the basic framework that I haven't been able to resolve (devstudio gives me an error when I want to load a few things here and there). So that project has been put on ice.

As for other projects, a while ago I continued some development of LibHTTP and got a bit annoyed on my testing class. So I decided to make a testing framework based on unit testing. That's how UsUnit came to life. Because I wanted to include the source file and line where a check failed I had to write an UnrealScript PreProcessor, and I also wanted a few other features that a precompile could accomplish. And that's why I created UCPP. Well, UCPP had some releases, and it quite mature and finished right now. So I've gone back to working on UsUnit some more. I've already made one release so far. But this was mostly to put out the first binary package for people to play with. You could consider it a beta release for now. I want to complete just a few more things for the next release, it can be summed up into: finish the webadmin module.

Also, today barnEbiss contacted me if I was interested in helping him with a weapon mod. His idea is quite interesting. He wants to create a weapon that allows you to create a line of gasoline and set that one fire (the fire ofcourse will hurt people). It's quite an interesting weapon to create, with some interesting implementation issues to solve. So I will also be working on that project.

Well I guess that's all I have to say about that for now.

Thursday, September 15, 2005

R.I.P. Free PowerDNS express

PowerDNS express is no longer free. It used to be completely free for pretty much unlimited control over 5 domain names. It's a great service and the interface to manage the DNS entries was clean and simple enough. But because of various reason they can no longer provide the service for free. Too bad, I really liked it. Since my registrar also provides DNS services (my previous registrar didn't that's why I used powerdns) without extra cost I've switched to that one. Thier interface isn't as nice as the one provided by powerdns, but it doesn't cost me at least $8 a year. So here powerdns, some free advertisment in return for those years of free service.

Sunday, August 14, 2005

LbaWin - Little Big Adventure

I'm a big LBA fan, have been since I first got the game (june 1995). I completed the game so many times I've lost count. After a certain point it's no longer fun to play the game because you know every little thing in the game. So I stopped with that. After a while one of the team members that made the game poped up with a windows port of the game (LbaWin). Since he was doing it by himself he could use some beta testers. I decided to help him out (just like quite some others) and started to play the game again, but this time to find bugs. I did that for quite some time. But before the development of LbaWin came to a stop I already got sidetracked from playing the game. So it has been quite some time since the last beta release of LbaWin. And for some reason I wanted to play LBA once more. Installed the game and started playing, only took me a few hours to complete the game once more (in all it's glory). I still know exactly what to do. The game just looks so small when you know what to do and where to go. But the fact remains that it actually is still quite a large game if you compare it to the time needed to complete other games. I mean, the first time I played LBA it took me quite some hours to finish it. I've played other games that I completed the first time in just a couple of hours. Ofcourse you could strech the game, but that might just make it boring. LBA is still a awesome game, I just want something new to explore. (note: stil have to replay LBA2, haven't done that in some time now)

Coming back to the point of something new, LBA has quite some places that could be expanded (made larger). And there are quite some places where more world could be placed between some scenes. It would be great if these things could be expanded. And maybe even add some side quests.

Some people in the LBA community continued work I started years ago and already made some tools to view and even edit the scenes in the game. Additional tools to compile story code and stuff like that are also being worked on.

Tuesday, August 02, 2005

Readonly UnrealWiki mirror

BeyondUnreal has been offline for a couple of days now. And because the UnrealWiki is hosted on the same machine so is that site. It kinda sucks, because now nobody can get any information from that site, unless they have a copy of the offline unrealwiki. I've created a UnrealWiki mirror using the offline copy. It's not perfect but at least you can still view all documents. The offline copy isn't great to use as a mirror because the case of the characters in the page names have been lost and subpages don't exist on-disk. So a direct link back to the original wiki page isn't possible (unless when you use the link at the bottom). It would be nicer if there was some way of distributing the unrealwiki over multiple servers, but I guess the wiki engine must be designed for that or else you would get annoying edit conflicts.

Wednesday, June 15, 2005

UsUnit + UCPP

Well I laid my plans for a VS.Net Package aside for a while, kept getting annoying errors outside my source code. I'm been working on a UnrealScript Unit Testing Framework, somewhat similar to DUnit and JUnit. It's called UsUnit. It's almost done, but UnrealScript doesn't allow me to do certain cool things (like point out what check() failed). For this I started to create a PreProcessor for UnrealScript: UCPP

UCPP stands for UnrealScript (Class|Code) PreProcessor, the extention for UnrealScript classes is .uc so therefor UCPP, I'm not sure what the 'c' stands for. So far I've implemented quite some useful features:

  • #define NAME VALUE
  • #if EXPR (#else) #endif
  • UpperCase words in the code are replaced with thier definition according to a previous #define statement
The expression in the #if is quite extensive, simple boolean evaluations and some basic math functions.

But my current problem is with defining function macros:

#define DUMMY(a,b) DoSomething(a, b)

DUMMY("bla", 12345) -> DoSomething("bla", 12345);
I'm having problems to create a nice way to implement this feature. I don't want the definition list to be depended on a parser, but how do I process the definition to replace the arguments. a should be replace, but aa or "a" shouldn't be replaced. A simple replace text routine won't work. I could write an event
OnParseArguments(args: array of string; func: string; var OffsetList: TListOfSomeSort)
args
the argument names as specified in the name; this is simple to parse
func
the function part of the definition
OffsetList
Will contain the positions of the of the argument names in the function string; length isn't required since it's known.
The user will then have to assign a function to this event that will do the real parsing. However, this doesn't solve the magic entities in the macro definition (e.g. # and ##).But I guess that can be hacked in to the offset list in someway. Or I can add self and give direct access to the object that is actually being parsed.
The function definition only needs to be parsed the first time it's used. I can throw an exception when a definition can not be parsed because the event is not assigned.

Saturday, April 23, 2005

VisualStudio.Net Add-in written in Delphi, part 2

Ok, adding a new tool window wasn't hard at all, actually it's quite simple.

Just create an ActiveX form, get it's GUID from the type library window View -> Type Library and call the following functions:
myToolWindow = DTE(Application).Windows.CreateToolWindow(AddInInstance, 'your_library.activex_form', 'Some Title', '{THE GUID}', dummyIDsipatch);
The form is just like any other form in Delphi, you might want to set the form's AxBorderStyle to efbNone.

One ting, when creating an activex form Delphi automatically changes the target extention to ocx, I didn't like that and changed it back to the normal dll. Also, don't forget to register the "ActiveX Server" when you added a new COM object, otherwise the GUID won't be registered in the registry.

Friday, April 22, 2005

VisualStudio.Net Add-in written in Delphi

I'm planning to create a spin-off of UnCodeX (again), this is going to be an add-in for VisualStudio.Net. Right now Epic has a simple tool that gives a class and package tree, but compared to UnCodeX is kinda inferior. Since I have a lot of base code it would be easy to create an add-in right?

Well not completely, first the add-in creation is done via an wizard in VisualStudio, well great, but how would I do the same in Delphi?. The add-ins are all COM based, so I will have to import a type-library somewhere. The VS.Net wizard does all the base work, so I have a few pointers, like what interfaces I should implement. But I have no idea what type-libraries to import. After a long search and some pointers here and there I've found out how to create a Add-in for VS.Net in Delphi.

  1. Before you do anything you will first have to import and install the type libraries (to make things easier in the next few steps).
    1. Import and install the type library: Microsoft Add-Iin Desginer, the actual file is called: MSADDNDR.DLL.
    2. Import and install the type library: Microsoft Development Environment 7.0, the actual file is called: dte.olb.
    Make sure you installed them in a package.
  2. Now create a new ActiveX library; nothing major here, you just need it.
  3. Now in your library create a new ActiveX Automation Object.
    1. Enter any name you like; different from your library name.
  4. You will now see the Type Library tool, select your library in the tree and open the Uses tab.
    1. Right-click the list and "show all type libraries"
    2. Now select the same type libraries you previously installed.
  5. Now select the Automation Object you created (it's the one not prefixed with an I)
    1. Select the Implements tab
    2. Right click and add _IDTExtensibility2
    3. Right click and add AddIn
    4. If either one of these are not available you messed up in the previous steps.
  6. Close the type library tool window.
  7. Save the new unit (Save all files i the project)
  8. Now add the following to the interface uses list: , EnvDTE_TLB, AddInDesignerObjects_TLB
  9. If everything is ok you should be able to compile the library.
  10. After the compile is done you should register the library via the menu Run -> Register ActiveX Server
  11. Now you will have to add an entry to the registry so the add-in will show up in the Add-in manager. Add a new key to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1\Addins\. The key name should be: <library name without extention>.<automation object name>
  12. The add-in should now be visible in the add-in manager

If you want to change the descript and version information in a later stage just open the .tlb file in Delphi. This will pop-up the type library tool.

These are just the basics for a add-in, how the rest works is still a mystery, but I hope to solve it soon and report it here. Next thing might be how to add your own tool window, I assume this can done via an ActiveForm. The tool windows are refered to via the GUID in VisualStudio.NET, so it would be some more ActiveX\COM stuff.

Wednesday, April 13, 2005

Delphi 6 + build configuration

Delphi 6 misses (at least) one important feature: being able to create\manage build configurations. For my UnCodeX project I want two build configurations: debug (or development) and release. For the simple reason that the debug builds will include debugger information so I can use some tools to find memory leaks and what not. The release builds ofcourse should not contain the debug info and should be optimized. But Delphi 6 was no way to manage the project options\settings. You can have various "desktop" configurations, really don't see the use of that, but not build configurations. So far I've only found one IDE expert that helps me a little bit: GExperts. However, the way I have to use this isn't great at all, the overview of te configuration is completely lost and it doesn't store the alternate configurations on the project. This way I can't include it with the CVS and use the alternate configurations on other machines. This sucks a lot.

I don't know if newer Delphi releases do support management of alternate build cofigurations, I don't have the money to upgrade to a newer Delphi release anyway. Delphi 6 still works well enough for me, except for a couple of annoyances.

If anyone knows of an IDE expert, or maybe an other method, that makes this easier please let me know. Important to note that this tool has to be free (as in beer), or at least with a small price tag, because I don't want to limit people in being able to work on my open source uncodex project.

Thursday, April 07, 2005

UnCodeX releases

I think I need to make my release schedule for UnCodeX a bit shorter. It has been almost 1 year since the last stable release. And I've only had a few major stable releases since the beginning. So right now, I'm going to finish all tasks that have a priority of 7 or higher and then I'll release a stable version.
Ofcourse I also need to update quite some documentation, specially the PascalScript part requires a lot of documentation work. I'm not really looking forward to do work on that part of the documentation. But there's not much choise.

I hope to release a new version before the last one is a year old, I think two weeks, but maybe a little more.

Open Source, it's nice.

I'm not going to stay Open Source is the way to go, or that everybody must switch to open source (altough it would be very nice).

I'm working on a fully Open Source programms (UnCodeX), and while working on it I sometimes use other open source tools (FreePascal compiler) and components (RemObjects' PascalScript). Both the examples are open source (and free software, in a way).
PascalScript didn't compile for FreePascal out of the box, but because the source was available I could apply the changes required to make it compile. I mailed my changes to the developers and they applied them to their SubVersion repository. Now everybody can enjoy PascalScript in FreePascal.
As for FreePascal, the ini file classes provided by Borland in Delphi 6 didn't meet up to some of my requirements, and because of the private vs protected shit I could override some functions. FreePascal provided similar classes, and because the license of FreePascal is compatible with the license of UnCodeX (both are LGPL) I could use the FreePascal implementation and make my adjustments. While I was making some adjustments I discovered a few bugs in their implementation (the Delphi memory leak detection script by Vincent Mahon helped me to find one of them). I reported the bugs I found, and the fixes for it, and they have been applied to the standard distribution of FreePascal.

So, for at least two projects I found some issues, was able to fix them and contributed the fixes back to the creators. They helped me, I helped them in return. Sure, there are a lot of people that don't help out. But why shouldn't you? What would be the reason not to help others out that helped you at the first place. Please that report bugs are great, people that report bugs with correct patches are just awesome. And you can't create patches when you don't have source access.

Tuesday, December 21, 2004

Private vs Protected

Pretty much every object oriented programming language let's you set the visibility of object members. Usually it defaults to public. That means everybody can access that member. Ofcourse often you don't want to other objects to access certain parts of your object. This is where private or protected come in to play.

Limiting members access

An object should only expose members that really need to be accessed from the outside. All other members should be "hidden". It's not just a security issue but also creates nicer foot prints to work with the code. For example IDEs only have to list the public accessable functions in their "code insight" (or whatever you want to call it) listing. The public members are the members to work with, it also makes it easier for you to find what entry points you need to use on an object (in case it's not your code).

Private

The actual outcome of this depends on the language. But usually it comes down that only the objects within the same scope can access this member, subclasses do no have access to this member. What the scope is depends on the language used, often the scope is just the object itself. In ObjectPascal however the scope is the unit file (the source code).

One of the basics of OOP is that you can extend an object and add additional functionality. And usually you can only add additional functionlity outside of the "scope" because you can either not touch the original source or you simply shouldn't.
Using private to protect members of an object will prevent an subclass to work with these members. This is often needed.

Protected

Protected is similar to private except that subclasses can always access these members no matter if they are in the same scope.

Making members protected opens a security issue for those members. Since a subclass has access to these members it's possible to work around security measures.

How to choose

I'm sure somebody already though about that, however I am not aware of a document that introduces a formal method for member accessability. If such document would exist it would be very technical for most programmers to understand, or at least it would way to time consuming. That doesn't mean it's not wise to read it and use it's methods.

Here's a simple classification scheme I think should work well enough for most people.

  1. Is the member valuable to access from other classes? (1)
    Yes -> go to 2; No -> go to 3.
  2. Is it a variable?
    Yes -> go to 2.1; No (it's a function) -> public
    1. Should this variable be read-only? (2)
      Yes -> create a public accessor function and go to 3; No -> public
  3. Does the member contain\give access to security sensitive information? (3)
    Yes -> go to 3.1; No -> protected
    1. Is it a variable?
      Yes -> go to 3.1.1; No -> go to 3.2
      1. Should a subclass be able to write this member?
        Yes -> go to 3.3; No -> go to 3.1.2
        1. Should a subclass be able to read this member?
          Yes -> private and create a protected accessor method; No -> private
      2. Does this member give readonly access?
        Yes -> go to 3.2.1; No -> go to 3.3
        1. May a subclass read this data? (4)
          Yes -> protected; No -> private
      3. Does the new value need to be validated? (5)
        Yes -> private and create a protected method that will validate and set the private method; No -> protected
Only in a few cases the member will become and isolated private member (e.g. unable to read\write to the member).

1.
This is quite a difficult question, is the member for internal use only? When is something for internal use only? Things like buffers and pointers are usually for internal use only. Maybe somebody else can shed some light on this question.
2.
Very often you want to be able to give other classes access to certain variables, like the current position of a parser, but you don't want them to be able to modify the value. For this you should create an accessor function getMyVariable() that will simply return the current value of the variable.
3.
When is something security sensitive? Things like keys and passwords and sensitive. But it's not limited to authentication related information, sometimes things like an URI could be sensitive. Things that might need to be validated before they are used are security sensitive. For example in games you might want to give a user the freedom so configure some client side things. However, these things could be abused for cheating. So the settings need to be validated before they are set.
4.
In only a very few cases you want to prevent a subclass from reading certain variables. It's pretty much only the case for keys and passwords. Even though a subclass might have set the value via an other method it still doesn't mean it should be able to read a password.
5.
In some cases you want to give a subclass the right to set a new value, but you also want to validate the new value to meet certain security measures. For this you need to make sure the subclass has to use your method to set the new value and not be able to override it with it's own faulty method. Most languages provide the means to do this (UnrealScript allows you to mark a function as final, thus preventing it to be overwritten by a subclass). There is a trick to do this. Simply make the member private so it can't be accessed from the subclass and create protected accessor methods (get and set). In your set method you will validate the new value and pass it to the protected member. This way subclasses will have to use the parent set method in order to write the new value.
 //pseudo code

 var private string SensitiveInfo;

 protected function bool SetSensitiveInfo(string newValue)
 {
  if (newValue doesn't meet constraints) return false;
  SensitiveInfo = newValue;
  return true;
 }

 protected function string GetSensitiveInfo()
 {
  return SensitiveInfo;
 }
 

Thursday, October 14, 2004

MSIE and the <button> tag

MSIE doesn't really support the <button> as defined in the HTML 4 specification. Sure it does render a button, and something happens when you push on it. But it doesn't work as specified.

Why use <button> instead of a <input type="submit" ... />?

Simple, <button> gives you more power. For example, with the <button> tag the text on the button is different that the value submitted when the button is clicked. this is very usefull when you want to use a nicer description and don't want to use ugly value checks in your backend script.
<input type="submit" name="mybutton" value="add this new entry" /> displays:

When submitted the following details will be received by the back end script: mybutton = "add this new entry"
Sure it works when you only have only one button. But what if you have two buttons:

Now you will have to check the value of the action variable. It would be much nicer in the code if that value would be addChild or addSibling (also better for localization). But this is not possible with the <input> element.
That's where the <button> tag is usefull:
<button name="action" value="addChild" />add as child<button></button name="action" value="addSibling" />add as sibling</button> produces:

Depending on which button is pressed the value of action would be either addChild or addSibling while the text on the button is descriptive.
Another thing about the <button> is, that it's easier to use for style sheets, you don't have to set a special CSS class for all buttons (since not all Browsers support Input[type="submit"] elements in CSS).

But MSIE is broken

The <button> in MSIE doesn't work as it should. Instead of sending the value of the value property, it will send the value of the innerText (note: this is documented on MSDN), in other words, it will just behave like a normal <input> .
Another thing is that MSIE will include all <button> elements in the submit data, not just the one of the pressed button. So you would get something like: ?action=addChild&action=addSibling. This makes the button element complete useless since you don't know what button was pressed. This incorrect behavior isn't even documented on the MSDN.

A ugly workaround

I came up with an ugly workaround for just MSIE. It uses some javascript. Instead of creating a submit button I will create a normal button: <button type="button" onclick="onButtonClick(this, 'action', 'addChild')">Add as a child
Note, no value and no name have been set, this is very important. When this button is clicked it will call the following JavaScript code:
function onButtonClick(btn, name, value)
{
 btn.name = name;
 btn.value = value;
 btn.form.submit();
}
This will simply set the name of the button pressed to the desired name and set the value. After which it will submit the form.
Now when the button is pressed the text on the button will change to the desired value (yep, that's also incorrect behavior). But the form is submitted at once so it doesn't hurt a lot.
This bug exists in all MSIE versions that support the <button> tag, up to MSIE 6 sp2.
If everybody would switch to browsers that did support the standards as defined (like Mozilla, Firefox, or Opera) it wouldn't be a problem.

Friday, October 08, 2004

UnrealWiki Dev Journal 27-09-2004

UnCodeX Tribes:V ponderings:

Interfaces

Currently, there's only one root for the class tree. I'm going to add a new root item "Interfaces" that contains all interfaces.

Interfaces don't have parents, so this would be the best choice.
Things to think about:
  • auto expand Object works differently with more than 1 root node
  • no create subclass menu item for interfaces

Defines

I may have to redesign my complete parsing system. Maybe have to move it to a single pass parser. Right now I first construct the class tree, after that I analyse all the classes. This might not be possible anymore because of the #if ... #endif macros.
I'm pretty sure it's not possible to have a different class name, however, it might be possible that the parent class can be changed using these macros. So I would have to construct the tree and analyse the packages at the same time so all #defines are catched. The best method might be to mimick the way the unrealscript compiler does it: per package. This ofcourse would re-introduce the package order mechanism. This would be the nicest solution.

The other solution would be to extend the package scanner to parse through the whole source file every time just to capture the #define, #if...#endif macros.
Another thing I need to know is if the #define macros are system wide, or only for the subclasses. Most #defines are afaik in the Object class, so that would automatically make them system wide.
Also I would need to implement a expression evaluator for the #if macro.

Imports

Depending on what the import directive does I might have to implement this too. Mostlikely it's just identical to the #import macro, which will simply import type declarations. In this case I don't need to change anything (except to ingore the import lines).

Friday, September 24, 2004

UnrealWiki Dev Journal 24-09-2004

LibHTTP 3 is getting pretty solid. I've added a test class to perform various requests. I already found a few minor bugs using that test class, bugs that have been in there for quite some time.
The build is currently 133KiB, I'm not going to strip source from the package because of the simple reason that you can no longer use the package during compile time, only run-time. Stripping the source would reduce the package to 54KiB.
I've been thinking about creating a better source stripper. It doesn't strip the complete source, only the function and state body. The result would be that the TextBuffer (that usually contains the source code) only contains the declarations. This should be enough to use the package for compiling, and have a minimal size. I would add a comment to the top of the TextBuffer explaining that the code was removed to reduce size and stuff. However, creating such a tool isn't every easy. You can't simply replace the TextBuffer with a new one, you will have to update all the offsets in the file. Note that this tool is not for code protection, because you can still decompile the package. It's just to reduce the size.

Sunday, September 19, 2004

UnrealWiki Dev Journal 19-09-2004

Well found some time to work on LibHTTP version 3. So far I've made the following changes:

  • Improved easy of use: get(), post(), head()
  • Support for multipart/form-data POST data
  • Two different transfer modes: Normal and Fast (tries to download as much data as allowed within a single tick)
Previously you had to use HttpRequest to perform a request. I made this function protected and added functions for each HTTP request method. The HttpRequest function wasn't really a nice way to perform requests. Now you will have to set the cookie data before doing a request. You can't include it with the request function (was kinda useless).
As for the POST request, now both x-url-encoded data and form-data request bodies are supported. I've added some easy to use functions to add form-data fields. Using multipart/form-data you will have much more control over the posted content, for example it's possible to use Base64 to send binary data.
I also added a additional transfer mode: Fast. This will try to download as much data as allowed (defined by a couple of variables) within a single tick. This is usefull when you need to make sure certain data is downloaded as fast as possible and system impact isn't a big issue.

That's pretty much all the ideas I had to put into the new LibHTTP version, if you have requests, let me know ASAP.
Also LibHTTP3 will be shipped with the source code stripped from the binary package. This is to reduce the file size (87 KiB vs 33KiB).
Ofcourse the source code will be included seperately with the package so you don't have to download it via CVS.