Show grouped-core-changes095.txt syntax highlighted
==================================
POL CORE 095 Categorized Changelog
==================================
POL095 Released on [some date]
Major Items of note:
Siginifcant Speed Improvements
Better Memory Usage
Many Crash/Exception/Exploits Fixed
Unicode Speech
Linux Multithread Issues Resolved
Better Client Support
We hope this new core will vastly improve your POL experience! Reports are it's faster, more stable, and
better than ever!
** **
**PLEASE READ EVERY ITEM IN THIS FILE, AS EACH ARE IMPORTANT TO RUNNING YOUR POL SERVER**
** **
**Documentation Site at http://poldoc.fem.tu-ilmenau.de**
Credits:
Development Team:
Syzygy
Racalac
Myrathi
Thanks to (sorry if I forgot you!):
Olor
Shinigami
HellRazor
Dasc
Austin
Ronald McDonald (mmm fries)
birdy
and more...
Everyone who helped in pol-core-test, and #POL!
==================================
Critical Items of Note:
*** ALL SCRIPTS MUST BE RECOMPILED!! ***
CRITICAL: You MUST add this to an itemdesc.cfg entry or you server will fail to start!
Container 0xFF02
{
Name WornItemsContainer
graphic 0x1E5E
Gump 0x003C
MinX 0
MaxX 66
MinY 0
MaxY 33
Weight 0
MaxItems 65535
Maxweight 65535
}
Note the objtype is in the core-reserved range of 0xF000 - 0xFFFF. I hope no one has any
items defined in that range.. :)
Important CFG change: Set Weapon 0xF020 to SaveOnExit 0. This will force the intrinsic NPC
wrestling weapon to a non-saved serial number.
xlate.cfg is no longer used, so any item "aliases" you may have (for example "gc" for "garlic") will no
longer be converted to an objtype. In these cases, you must add an itemdesc.cfg entry for them.
Default Container Limits have changed to 125 items, 250 weight. You may change these default limits in
servspecopt.cfg (DefaultContainerMaxItems, DefaultContainerMaxWeight). If you have existing containers
that exceed these limits, you may run into problems on startup. In this case, raise the default limits
to 150/65535.
POL now uses the MD5 hashing algorithm to store passwords. The pol.cfg option RetainCleartextPasswords
defaults to 1, meaning the real password is stored in accounts.txt. If you change this to 0, password
will not be stored, only the hashed version. The hashed version is always used for login authentication.
This means if someone forgets their password, the cleartext version is unknown. Reset the password and
POL will automatically recompute the hash (add back in a Password xxxx line in the accounts.txt entry)
The hashed strings are available through the account script object (who.acct).
Major Addition: You may now specify properties for an item during creation. Here are the mechanics:
polsys.em: GetItemDescriptor(objtype or name) returns a struct of all the itemdesc.cfg properties
for the specified objtype. You can use this to print the contents:
var ret := GetItemDescriptor(objtype);
foreach thing in ret
print(_thing_iter + ": " + thing);
endforeach
There are a couple special members. "CProps" is a dictionary of string->object pairs (object could be any
packable type). "StackingIgnoresCProps" is an array of strings. You may edit the values in this dict
but not all are assigned per-item (meaning it will do nothing). The item create functions accept this
dictionary in place of the objtype / objtypename parameter.
For example, to create a new item that will automatically stack with an existing stack with non-standard
color and cprops, it would look like:
var ret := GetItemDescriptor(objtype);
ret.Color := 0x10;
ret.CProps.insert("blah","1"); //assuming the existing stack have this color and cprop
ret.StackingIgnoresCProps.append("blingbling");
var item := CreateItemInBackpack(who,ret,10);
Renamed internal ".props" command to ".t_props". This script should replace it:
use uo;
program dot_props( who )
var what := Target( who );
if (what)
var names := what.propnames();
if (names.size() != 0)
foreach propname in names
SendSysMessage( who, propname + ": " + what.getprop( propname ) );
endforeach
else
SendSysMessage( who, "No properties." );
endif
endif
endprogram
**** A VERY SPECIAL NOTE ****
It would be best if you defined all your your objtypes in the range 0x5000 to 0xEFFF.
See notes under POL092-2000-12-11 for how to specify OldObjType in itemdesc.cfg to convert objtypes at load time.
*** END VERY SPECIAL NOTE ***
Exploit Fixes
Character creation will refuse to create a character with control characters in the name (newline, for example)
Fixed: Input is rejected for SendTextEntryGump if the string contains a control character (newline, etc)
Fixed: Generic Gump 'textentry' will strip out any control characters from user input.
Added control character stripping from sysbook text entry.
HP/MaxHP update to nearby clients now uses a standard MaxHP ratio against 1000 hitpoints.
This should stop people from being able to snoop a mobile's exact HPs via a packet sniffer.
Fixed: Various buffer overflow exploits in various uo.em functions (eg PrintTextAbove())
Text-color is validated between 2 and 1001 to prevent client-side
exploits. Invalid color prints a message to console:
e.g. Client #1 (account test) speaking with out-of-range color 0x1
Anti-exploit checks in uo::SelectColor()
now validates values as 2 to 1001 to prevent client-side exploits:
- returns the chosen color value
- or an error ("Client selected an out-of-range color")
An error situation will also display information on the console:
e.g.
Client #1 (account test) selected an out-of-range color 0x1
Fixed: Players cannot rename a mobile with an invalid string. If any character in the new name is invalid,
the rename is rejected. Valid characters are spaces and upper- or lower-case letters (A-Z)
Fixed: An exploit that allowed players to drag items onto far away mobiles.
Fixed: a bug with system books where bad characters were written to the save files, causing errors
like "Item has no SERIAL property".
Crash Fixes
Fixed a crash caused when a script accessed container.container on something in a mob's backpack.
Fixed: MoveCharacterToLocation with an offline character could cause an exception.
Fixed EnumerateItemsInContainer crash (with "worn items container" who.backpack.container)
Fixed: Exception if no regions were defined.
Fixed: using an item's x,y,z members in its own create script would throw an exception.
Fixed a crash bug in CanRemove and OnRemove script execution when there's no owning mobile
Added: sturdier parameter checking for object member-functions (no AV when too few params)
Fixed a crash bug with cheaters sending an invalid packet.
Fixed a problem with listening points that would cause big problems after
listener destruction (house doors, tillermen, wink wink, nudge nudge)
Performance Changes
Major changes to the script engine:
*** ALL SCRIPTS MUST BE RECOMPILED!! ***
All scripts should function as they do now, with two exceptions:
.smember no longer works
the hidden iterator variable in "foreach" is now called
_(var)_iter instead of _(var)_counter
Fixed two major script object leaks.
Internal changes to the way member assignment and access works.
Internal changes to the way script substrings are handled.
Removed the 'Substring' object type.
Fixed: len() on an error would return random values
(now returns the number of elements in the error dictionary,
which is probably unnecessary)
Sped up system load
Preload 'equiptest' and 'unequiptest' scripts, to speed system load time.
(however, equiptest/unequiptest scripts created after startup will not be noticed)
Changed config file handling to speed load time.
(menus.cfg entries might have their elements reordered, though)
Sped up storage area lookups
accounts.txt will no longer be reloaded after a new version is written by pol itself
Very Significant speed improvement for all SystemFindObjectBySerial calls (including internal ones)! Your
start-up times (with CheckIntegrity enabled) should be vasty improved.
Script Fixes
Fixed: NPC weapons will use the hitscript specified, not the wrestling hitscript
Fixed: "npctemplate" was not initialized on start-up when the exported vital functions were called.
Fixed: RadToDeg() and DegToRad() in MATH.EM. They now work the right way around. :)
Fixed: client version string was being limited to 10 characters.
Fixed: "TrueObjtype" was not read correctly on startup.
Fixed: coordinate bounds checking for CreateNPCFromTemplate and CreateMultiAtLocation (still be careful with
this latter one, if some part of the multi overlaps beyond the map edge, it will cause problems)
Fixed: unequiptest and equiptest are now automatically reloaded after an .unload or .unloadall
Fixed moved some npc creation code around so now npc.npctemplate is initialized by the time the vital maximum
and regen rate exported functions are called. (so grabbing the HITS property from the npcdesc element is
successful)
Fixed: Buying stackable items from NPC merchants now call canInsert and onInsert for player's backpack.
Fixed: Setting .buyprice and .sellprice to 0 means the item's price is 0, not itemdesc default. (setting the
members to -1 will force them to default to itemdesc)
Fixed an assertion failure when assigning to a non-integer element of an array
test script: "var a := {}; var b; a[b] := 3;"
Fixed: item.multi should now return the correct MultiRef (items on tables and other 'blocked' locations
were not being processed correctly)
Fixed: polcore().clear_script_profile_counters() shouldn't complain if you pass 0 parameters (the correct amount)
Fixed: CreateMultiAtLocation now returns a MultiRef, not an ItemRef ;)
Fixed: item.invisible will initialize based on itemdesc.cfg settings
Fixed: Text command scripts now have their controller properly set. (character reference in
canInsert scripts where being passed as uninitialzed when the script was started via a
textcommand)
Fixed: .hp, .maxhp_mod, for weapon and armor items should be writable again.
Fixed: .buyprice and .sellprice were returning 0 if you didn't write to them first.
Now if they are not written to first, they will return the itemdesc value for
VendorBuysFor and VendorSellsFor.
Fixed a bug in SystemFindObjectBySerial where items in the secure trade container and
the item held on a character's cursor were not being found.
Fixed a bug with character.concealed being misread on server start as a boolean (0/1), not
an integer(0-255)
Fixed a bug with the conceal system where if a character's concealed level was reduced to
a value still greater than 0, other characters of the same new concealed level did not
see the character.
Fixed MoveItemToContainer bug (default container coords of -1 was being flagged
as out of range). Reminder: any value of x or y outside the gump coordinate
range as defined in the container's itemdesc.cfg will be interpreted as "random location"
item.color := (value) will once again set the color properly.
The game clock will initialize before any objects are loaded from data files.
RecalcVitals will not operate on offline mobiles
Script Changes
account.GetCharacter and account.DeleteCharacter will no longer accept an index of 0
Added uo.em function: ListMultisInBox(x1,y1,z1, x2,y2,z2) lists multis that have at least one static within the volume specified.
Resurrect() will return an error if the mobile's location would be blocked if the mob were alive (ie by a door)
Resurrect takes an optional parameter. If you pass RESURRECT_FORCELOCATION, will not check for blocking objects.
Be sure you know what you're doing if you pass this flag.
mob.backpack.container now returns a mobileref to the owner.
ondelete scripts are now passed an offline mobileref.
AppendConfigElem will either accept an array of arrays, as it does now,
or an array of struct { name, value }
Added to polsys.em: SetSysTrayPopupText( text )
Target() will return a proper multiref if a multi is targetted (usable with DestroyMulti etc)
This does not apply to floors, etc - only ship masts and so forth.
process.kill() will immediately kill sleeping scripts, as well as scripts being debugged.
(previously, script process would not die until the script woke up, if it was sleeping.)
Added boat.em: MoveBoatXY(boatref,x,y)
Changed the order of calling the Vital Maximum and Regenerate functions via RecalcVitals().
Order is: Maximum function, Regenerate function. Also, call Attribute Intrinsic Modification
exported functions before Vital Maximum and Regen.
foreach will no longer iterate over error objects
Added ReadMillisecondClock() to polsys.em
Removed hardcoded death sounds for human characters.
Added: obj.set_member(membername, value) and obj.get_member(membername) to replace the removed "." method.
This sets/gets a built-in member on the object which is named "membername". Returns an error if the
member was not found on that object (i.e. "dmg_mod" on a backpack).
Added: account.CheckPassword( password ) -- for validating an account's password
(returns 1 if the password is correct)
Added: player.clientversion -- returns the client version string or an empty string
if the client has disconnected.
Added Character method: character.GetGottenItem() returns itemref to item on player's "cursor"
Added Character Method: character.SetWarmode( 0/1 ); Sets the internal warmode flag and sends the
update to the player. Returns the new warmode value.
Added: CFGFILE.EM function ListConfigElemProps(element): returns an array of the
element's property-names (as unique strings).
Added: UO.EM function CreateItemCopyAtLocation(x, y, z, itemref): makes a clone of the item
referenced with "itemref" at location x,y,z. Copies member variables and CProps. Does
not work with Multi objects. Does not copy a container's contents.
Added: Unhiding AND Unconcealing generates a SYSEVENT_ENTEREDAREA event for nearby NPCs.
Added to POLSYS.EM: ReloadConfiguration(). Loads npcdesc.cfg and pol.cfg
Removed: account.SetAcctName() member-function (deprecated since 089!)
- use instead: account.SetName(name)
Added new uo.em function: SendQuestArrow(to_whom, x := -1, y := -1)
- 'to_whom' is the character the arrow shows to.
- Passing 'x' and 'y' within map bounds will set the Quest Arrow to point at that location.
- Passing -1 as 'x' and 'y' (ie. by just called SendQuestArrow(to_whom)) will remove it.
Added: OS.EM function: is_critical(). Returns 1 if the calling script was set critical, else 0.
New os.em function: clear_event_queue(), empties current script's event queue.
Added a new object method: script_process.clear_event_queue(). (script_process comes from
NPC.process or uo.em's getprocess(pid))
Added a new os.em function: set_event_queue_size(newsize) : Changes the maximum number of
events the current script will keep in the queue (additional events will be discarded).
If not called, the default size is 20 events. The function returns the old queue size.
Added new uo.em function: ListItemsNearLocationWithFlag(x,y,z,range,flags). "flags" here are
tiledata.mul flags for the item's graphic. Find only dynamic items with any of the flags
OR'd together, not statics. A list of known flags is in the new uo.em.
Updated item.facing - valid range is now 0-127
Script Object Changes
escript: array + array will return a concatenation of the arrays:
{ 3,2,6 } + {6,4} returns {3,2,6,6,4}
structs are now totally different objects than dictionaries. They can only contain named members,
and the [] operator no longer functions on them.
Also, struct names are now case-insensitive
For structs, you should use operations like this:
var a := struct { x, y, z };
a.x := 5;
var b := struct;
b.+g := 6;
For dictionaries, you should use operations like this:
var a := dictionary;
a[57] := 4;
a["XY"] := "Z";
a.erase( "XY" );
structs will again allow the obj[ keyname ] syntax, but only for strings.
if you pass a number, your script will abort. If you pass another kind of object,
an error will be returned. This is meant to help you quickly find cases where a script
pretends that a struct is an array, which is not the case.
SaveWorldState() now returns a structure on success:
struct { CleanObjects, DirtyObjects, ElapsedMilliseconds };
Added: account.PasswordHash (password only hashed), and account.UsernamePasswordHash (username + password
hashed). account here is an account script object, i.e. character.acct.
Added array.exists( index ) - returns 1 if index <= array.size(), otherwise 0.
Fixed: array member-functions (.erase(), .size(), etc) now enforce parameter-passing:
if you pass the wrong number of parameters (too few -or- too many) they'll return an
appropriate error (until now, passing too few caused an Access Violation! Argh!!!)
Fixed: arrays will no longer "resize" when you attempt to *retrieve* a value from an index
that doesn't exist. Setting a value in a non-existant index still resizes, as always.
Test array.size() or check array.exists(index) as appropriate.
- Example:
var arr := {1,2}; // create array with arr[1] and arr[2]
arr[4] := "test"; // auto-enlarges to 4 indices (arr[3] is uninitialized)
var foo := arr[23]; // arr.size() is still 4 and it returns:
// error{ errortext = "Array index out of bounds" }
var bar := arr.exists(15); // bar holds 0 since arr[15] doesn't exist.
var zim := arr.exists(3); // zim holds 1. arr[3] exists, even though it's uninit!
TypeOf() (see basic.em) on Dictionary and Struct variables now returns "Dictionary" and
"Struct", respectively.
foreach now operates over dictionaries:
foreach v in dict
print( _v_iter + " -> " + v );
endforeach
escript: added more convenient syntax for declaring structures:
var t := struct { a, b, c }; // basic
var t := struct { a := 4, b := "hey", m := foo(bar(4)) }; // initialized
var t := struct { a := 4, b := struct { g,h,i }, c }; // with nested structures
Container Changes
MAJOR CHANGES: Script functions that add/move/delete items to/from containers will call that container's
canInsert, onInsert, canRemove, and onRemove scripts (where appropriate, i.e. if MoveItemToContainer
first moves an item out of the original container, caRemove and onRemove will be called).
As always, if canInsert or canRemove returns 0, the function WILL FAIL to move/add/delete.
ALWAYS check the return value of an core function for an error!
Also, since now scripts can call these container functions, it is possible the first parameter passed
(Character reference to player moving/removing item) is Uninitialized. You must check for this in your
can/on/Insert/Remove script!
Changed: OnRemove and OnInsert are now Run-To-Completion (i.e. CRITICAL) scripts.
*Containers will default to limits as specified in servspecopt.cfg* (if not defined, defaults: 150
items, 250 weight). MaxItems and MaxWeight properties in the container's itemdesc.cfg entry will override
these defaults.
Changed: With the CreateItemInContainer/Backpack functions, a new stackable item will not be added to
an existing stack unless the existing item stack has color equal to its itemdesc.cfg color property
AND has equal CProps as its itemdesc.cfg entry (not counting locally and globally ignored cprops)
Important: parameter order changed to make things more consistent:
adding an amount to existing stack:
canInsert( mob, container, movetype, INSERT_INCREASE_STACK, adding_item, existing_stack, amt_to_add )
onInsert( mob, container, movetype, INSERT_INCREASE_STACK, uninit, existing_stack, amt_to_add )
(NOTE: for canInsert, adding_item can be an uninit, if one of the CreateItem functions is merely adding to an existing stack.
By the time onInsert is called, adding_item is gone.)
adding new item:
canInsert( mob, container, movetype, INSERT_ADD_ITEM, adding_item )
onInsert( mob, container, movetype, INSERT_ADD_ITEM, adding_item )
CRITICAL: You MUST add this to an itemdesc.cfg entry or you server will fail to start!
Container 0xFF02
{
Name WornItemsContainer
graphic 0x1E5E
Gump 0x003C
MinX 0
MaxX 66
MinY 0
MaxY 33
Weight 0
MaxItems 65535
Maxweight 65535
}
Note the objtype is in the core-reserved range of 0xF000 - 0xFFFF. I hope no one has any
items defined in that range.. :)
Note this change just fixed a bug with backpack weight limits, and won't help "total"
character weight (including equipped items).
Added: extra 'movetype' parameter to Can/OnInsert and Can/OnRemove scripts.
The values returned in this parameter are as follows (new constants in UO.EM)
- MOVETYPE_PLAYER : physically moved (dragged) by a player
- MOVETYPE_COREMOVE : moved by the core (eg, MoveItemToContainer().)
And in the *Insert scripts only...
- MOVETYPE_CORECREATE : created by core (eg, CreateItemInBackpack().)
Added 'inserttype' parameter to Can/OnInsert scripts (constants in uo.em):
- INSERT_ADD_ITEM : seperate item is being added to the container
- INSERT_INCREASE_STACK : and existing stack in the container is having its amount increased.
Example:
use uo;
canInsert( mob, container, movetype, inserttype, adding_item, existing_stack, amt_to_add )
if ( movetype != MOVETYPE_PLAYER )
// allow any movement/creation by core functions
return 1;
endif
// insertion by a player must be validated
// ...extra code here...
endprogram
Minor overhaul for onInsert scripts:
MoveItemToContainer:
now calls onInsert script _after_ putting the item in the container.
CreateItemInContainer, CreateItemInInventory, CreateItemInBackpack:
now call the onInsert script _after_ putting the item in the container.
when adding to an existing stack, passes the "amount added" as noted in the POL092 changelog.
(it was passing the size of the existing stack)
When purchasing from a vendor:
onInsert called _after_ putting the item in the PC's backpack.
Changed: MoveItemToLocation now calls UnEquipTest and UnEquip Scripts if the item was equipped on a char.
Fixed: when a player buys an item from a merchant NPC, canInsert and OnInsert scripts are called
for his/her backpack.
Added: MoveItemToContainer and MoveItemToLocation both call the item's parent container's
canRemove and onRemove scripts.
Improved: canInsert script will be called when a stack of item is placed into the
backpack through the paperdoll icon
CreateItemInContainer and -Backpack will call the container's canInsert and onInsert scripts.
POL will attempt to find a character that owns this container. If one is not found (i.e.
container is on the ground, the CharacterRef passed to the passed to the canInsert and
onInsert scripts will be an uninitialized object (so, check to make sure it's valid before
using it).
Adding to a stack of items (manually and by a CreateItem script function) in a container will
call the container's canInsert and onInsert scripts. Note if a script initiates this action
(and the script has no character controller), the CharacterRef passed to the canInsert and
onInsert scripts will be an uninitialized object (so, check to make sure it's valid before
using it).
The core will no longer play sounds effects for items being inserted into containers (thus, they
aren't heard by everyone.). You can get the desired effects using the container's onInsert
script. For example, to get the different gold drop sounds in addition to the default one,
you might have in your container's onInsert:
if(item.objtype == GetObjtypeByName("goldcoin"))
if(item.amount >= 100)
PlaySoundEffectPrivate( who, 0x38, who ); //lotsa gold
elseif(item.amount >= 30)
PlaySoundEffectPrivate( who, 0x37, who ); //some gold
else
PlaySoundEffectPrivate( who, 0x36, who ); //a few coins
endif
else
PlaySoundEffectPrivate( who, 0x49, who ); //default sound
endif
Secure Trade Window Changes
Added: if a trade is cancelled, canInsert and onInsert scripts
will be called for the player's backpack. If the items cannot be inserted, they will fall
to the player's feet.
Fixed: active trades will be cancelled on character death.
Fixed: You will no longer be able to initiate a secure trade with a ghost (if either party is dead).
Added: AllowSecureTradingInWarMode=0|1 in SERVSPECOPT(.LOCAL).CFG (default = 0)
The STW is affected by the new default container limits (see container section)
Unicode Changes
You can now speak in unicode fonts, and use unicode strings in scripts (with restrictions, below)
Added: Anti-exploit checks & updates in UNICODE-speech code
Fixed Unicode speech (and a couple of possible buffer overflow bugs)
- Text commands are now properly recognised and run
Fixed: Unicode ghost speech (no longer shows in chinese)
Added "unicode.em" with Unicode support functions (refer to file for names)
- a Unicode "string" ('uc_text' param) is simply an Array of Integers.
- each Integer corresponds to a 2-byte Unicode character.
- each of the 4 functions must also be given a 3-character "language code"
- examples are "ENU" (US English), "ENG" (UK English), "RUS" (Russian)
New EModule: UNICODE.EM containing 2 new constants and 4 new functions.
_DEFAULT_UCFONT, _DEFAULT_UCCOLOR
BroadcastUC(), PrintTextAboveUC(), PrintTextAbovePrivateUC(), SendSysMessageUC()
- These functions act identically to their UO.EM predecessors except for the parameters.
- ** please note the "UC" function suffixes **
- Unicode "strings" are actually EScript Arrays of 2-byte integers, where each integer
is a unicode wide-character. (example uctest.src will be uploaded to CoreTest group)
These "integer codes" are always clipped (internally) to 2 bytes (value & 0xFFFF) and
a '0x0000' value will stop the end the string, regardless of the size of the array.
- Passing a non-array variable or an array with a non-integer value in it, as the
'uc_text' parameter, will throw an error. They MUST all be integers.
- The 'uc_text' array cannot exceed the current 'maximum speech length' of 200.
- LangCode's are 3-character identifiers for the language it's in: ENG, RUS, KOR, etc.
Passing a langcode string that's not 3 characters will throw an error.
Fixed: Integers must now be "Big Endian" (0x1234) and not "Little Endian" (0x3412).
Added: NPCs now receive 2 *extra* event-parameters when they "hear" Unicode speech:
- 'uc_text' is a "Unicode array" of 2-byte "Big Endian" integers (as above)
- 'langcode' is a 3-character, uppercase language code.
- these 2 parameters do not exist when speech is received from a non-Unicode client.
- Example:
var ev := os::wait_for_event(120);
if ( ev )
case ( ev.type )
SYSEVENT_SPEECH:
PrintTextAbovePrivate(Self(), "You said...", ev.source);
if ( ev.uc_text )
PrintTextAbovePrivateUC(Self(), ev.uc_text, ev.langcode, ev.source);
PrintTextAbovePrivate(Self(), "...in Unicode", ev.source);
else
PrintTextAbovePrivate(Self(), ev.text, ev.source);
PrintTextAbovePrivate(Self(), "...in ASCII", ev.source);
endif
endcase
endif
Added: Text-command scripts now receive 2 extra parameters when activated by
Unicode-enabled clients.
- Program blocks should now look like this, to take advantage of them:
program textcmd_mycmd( who, text, uc_text, langcode )
- 'uc_text' is a "Unicode array" of 2-byte "Big Endian" integers (see above) and
can be an empty array (uc_text.size() == 0).
- 'langcode' is a 3-character, uppercase language code.
- 'uc_text' will be an 'error' type if the Unicode input is "bad".
- 'uc_text' and 'langcode' will be uninitialized if no Unicode text is available
(ie, when a non-Unicode client types the command)
-Note- Text-commands should still be in an "English readable" character set!!
There is no guarantee that foreign character sets in script-names will work,
never mind Unicode character-sets, as the 'filename' is still matched against
the ASCII equivalent!
Added: UNICODE.EM function RequestInputUC(): works the same as UO.EM's
RequestInput() function except it takes 'unicode array' and 'language
code' parameters in place of the 'prompt' parameter. The 'item'
parameter is still simply a placeholder and a client cannot act upon
one of these functions if the other has already been called (you'll
get the "Another script has an active prompt" error)
POL.CFG Changes:
new pol.cfg option: AssertionFailureAction = abort/continue/shutdown/shutdown-nosave
abort: (like old behavior) aborts immediately, without saving data.
continue: allows execution to continue.
shutdown: attempts graceful shutdown
shutdown-nosave: attempts graceful shutdown, without saving data.
If the assertion occurred during execution of a script, either 'shutdown', 'shutdown-nosave', or 'continue'
will abort that script, displaying the script name and PC.
Added: RetainCleartextPasswords (default 1). We now ALWAYS MD5 hash passwords and ALWAYS store them. Make this
option 1 if you want to also retain normal passwords, 0 if you only want the hashed passwords stored.
ListenPort is now optional. If you don't set it, or set it to zero, it won't be used.
New pol.cfg option:
MaximumClients=X
Denies logon to clients if # of clients connected is at defined maximum
Improvements to pol.cfg MaximumClients: cmd_level>0 is checked, and clients without
characters attached are not counted against the maximum.
Changed: MaximumClients in pol.cfg will be checked only after a character is selected to
play. Clients connected are only counted if they have attached characters (so a client
waiting to log in is not counted, and neither is a client that recently logged out).
Added: MaximumClientsBypassCmdLevel (default 1). This integer value (from 0 (player
cmdlevel) to 5 ("test") defines the minimum character command level to bypass the
maximum clients check. So if the option =1, counselors and above staff can log in if
the MaximumClients value is reached, but additional player cmdlevel characters cannot.
Added:
ReportRunToCompletionScripts=0/1 (default=1)
ReportCriticalScripts=0/1 (default=1)
- Set to 0 to remove the "Script X running..." (RTC) and
"Critical Script X has run for X instructions..." console messages.
Added: MiniDumpType=small/large, determines the type of crash dump created. "small" is the
normal minidump (default), "large" is the full memory space for POL (creates large files, but much
more useful to the developers). Case-sensative.
File.EM
Added file.em module:
ReadFile( filename ): read a text file
reads a text file
returns contents as an array of strings
removing newlines
WriteFile( filename, contents ): write a text file
contents is an array of strings.
appends newlines.
creates file if it does not exist.
renames existing file to filename.bak
AppendToFile( filename, morelines ): append to a text file
morelines: an array of strings
appends newlines.
creates file if it does not exist.
LogToFile( filename, textline ): append a single line to a text file
appends newlines.
creates file if it does not exist.
By default, no package has any file access rights.
config/fileaccess.cfg: reloadable config file, grants access. Example:
FileAccess
{
AllowRead 1
AllowRemote 1
Package testfileaccess
Extension .cfg
Extension .src
}
FileAccess
{
AllowWrite 1
AllowRemote 0
Package testfileaccess
Extension .txt
}
FileAccess
{
AllowAppend 1
Package *
Extension .log
}
Configuration File Changes:
servspecopt(.local).cfg:
Added:
DefaultContainerMaxItems (default 125) and DefaultContainerMaxWeight
(default 250). These values will be used for containers that do not define "MaxItems" and "MaxWeight"
in their itemdesc.cfg entries.
AllowSecureTradingInWarMode=0|1 (default = 0)
TotalStatsAtCreation (default = 65)
Takes comma-delimited lists of values and/or ranges (default = "65,80")
Example: TotalStatsAtCreation=65,80,90-95,100-110
UOFeatureEnable, used in the last dword of the 0xA9 login packet.
Probably has no effect (and possibly ill effects) until client messages like 0xBF 0x13 are handled.
pkg.cfg:
Added:
CoreRequired in pkg.cfg can now be a full version string (ie "POL095-2003-02-01" )
itemdesc.cfg:
Added:
UseRequiresLOS (defaults to 1 if not defined). If true,
Line-of-sight is needed to double-click the item. If false, a player can use the item
without LOS.* Note DoubleClickDistance is still checked.
GhostsCanUse (defaults to 0 if not defined). If true, dead (ghost) characters may double-click this item.
CanUseWhileFrozen = 0/1 (default 0)
CanUseWhileParalyzed = 0/1 (default 0)
Fixed:
itemdesc.cfg setting 'Invisible' not being used on item creation
HitScript will be read from itemdesc.cfg entries for weapons, and used.
OnHitScript will be read from itemdesc.cfg entries for armor, and used.
movecost.cfg:
Fixed:
movecost.cfg entries were being interpolated in the wrong order.
npcdesc.cfg:
AttackMinRange and AttackMaxRange will be read from npcdesc.cfg
xlate.cfg:
Changed:
xlate.cfg is no longer used.
console.cfg:
New console command [threadstatus] will display thread status and checkpoints
console.cfg is now reloadable (ReloadConfiguration, or SIGHUP)
spells.cfg:
Changed:
spells.cfg no longer depends on xlate.cfg for reagent name lookup - will use itemdesc.cfg names.
npcdesc.cfg:
Fixed:
npcdesc.cfg can once again hold non-"NpcTemplate" elements.
bannedips.cfg:
Fixed:
IP Banning via /config/bannedips.cfg (no longer stops at first element)
uoclient.cfg:
Added: (pkg)/uoclient.cfg can now contain a 'Protocol' element:
Protocol
{
#
# EnableFlowControlPackets: use the 0x33 (0x00 / 0x01) pause/restart packets.
# Though OSI seems to no longer send these packets, they seem to help with smoothness,
# particularly with boat movement.
EnableFlowControlPackets 1
}
Added uoclient.cfg property: MaxSkillID ("General" section,default 51 if not found). Use this depending on
what client versions connect to your server. Newer clients can handle more skill IDs and older clients
(which often crash being sent skillids above 48). You must have skills.cfg entires for each skillid up
to MaxSkillID.
uoclient.cfg can now specify multiple ports to listen for clients on, and the encryption to use with each.
Here is an example:
Listener
{
Port 7011
Encryption ignition
}
Listener
{
Port 7012
Encryption 1.26.4
}
Note that the Port specified overrides the value from servers.cfg.
if you're using Listener entries in uoclient.cfg, you should set ListenPort=0 in pol.cfg
OS-specific Changes
Windows:
POL can now run as a service (Windows NT/2000/XP only):
1. Put the executable in your POL directory (as always...)
2. Run 'pol -i' to install. 'pol -u' will uninstall if needed.
3. Recommended: Use the service manager to change the login from 'LocalSystem' to some account.
4. Start the service
There's now a little system tray icon that will let you stop POL. Maybe later it'll let
you look at the console output or logs. We're accepting fan art for the icon :-)
You'll need to uninstall and reinstall the service (pol -u, then pol -i) for the tray icon
to be able to appear.
Windows 95 is no longer supported. Minimum (MS) OS required: Win98/NT4
Failure to bind the listening socket will now cause startup to fail on windows.
win32: we now retrieve CPU time used from the OS. This is reported as cputime, when sysload
is reported. cputime is read once a minute, and the value displayed is the number of microseconds used.
So, if cpuload is 10,000,000 then 10 seconds of CPU time were used.
Linux:
This is Rac's first linux build, and hopefully it's improved. Previously, linux builds were made
using STLport and NO compiler optimizations. This build was made with libstdc++ 5.0.2, glibc 2.3.2
(with linuxthreads 2.3.2), gcc 3.2.2, and kernel 2.4.20. Consider using the same version libs as these.
Also, optimizations are turned on in this build (they were turned off because of inexplicable segfaults.
Hopefully, new build lib versions help this).
Added: Linux console command support
Linux: HUP signal will cause ReloadConfiguration to be called.
Fixed an assertion failure in SendOpenBook on Linux systems
Use sigaction() instead of signal() in hopes of correcting SIGPIPE problems.
Decay Changes:
Added: DefaultDecayTime=# in SERVSPECOPT(.LOCAL).CFG (default = 10) - unit: minutes
NOTE: Only newly created or "refreshed" items will use any new setting! Existing
items and items which remain "untouched" will retain the old value.
Fixed: Picking up an item, failing to place it somewhere else and having the
action "undone" (by the core) will no longer reset the decay timer if the
"time until decay" is greater than the default interval.
Fixed: a nasty bug where items would not decay in certain areas (specifically, in a zone with
a multi house). Also fixes the related "items don't decay near multis" bug.
Fixed: If an item is defined as no decay on multis (the default), its destroy script was
mistakenly called when the item was not decayed. This is fixed.
Fixed an error related to multis which would cause decay to function sporadically
near multis, and to use memory without bound if items existed on multis.
Item Stack Changes
Fixed: Items split from a stack retain the CProps from the original stack.
Fixed: When combining two stacks of the same objtype (either dragging one stack onto the other, or
onto the container containing the other stack), the CProp lists of each item must match EXACTLY
in order to be stacked. So, if Stack A has cprop myprop i5 and Stack B has cprop myprop i6, they
will not be stackable by dragging. Similarly, if either of the stacks are missing a cprop the
other possesses, the items will not stack.
Added better stacking control over CProps: You can now specify specific CProp names that will be ignored when
items are being stacked. There are two ways to do this:
-Template level: new Itemdesc.cfg property: StackingIgnoresCProps, a space-delimited list of case-sensative
cprop names to ignore only for stacking items of this objtype. i.e.:
StackingIgnoresCProps propname1 propname2 etc.
-Global level: A new packagable config file stacking.cfg (can be in /config and/or any package) specifies
lists of CProp names that are ignored for all stacking items (duplicate names ignored). Structure:
Stacking
{
IgnoreCprops propname1 propname2 etc.
}
Ecompile changes:
new ecompile option: -C <config file path>
new ecompile option: -A
"Auto compile", I guess - compiles scripts in your PolScriptRoot and all enabled packages under your PackageRoot directories.
(like -r, but knows where to go, using ecompile.cfg)
fixed a compiler bug where the following would compile:
var a, b, c;
a := b { c, b };
Fixed: ECOMPILE will no longer compile files with .src/.hsr/.asp/.inc
*anywhere* in the filename. These extensions must now be at the *end*
of the filenames for them to be compiled! (fixes 'file.src.bak' bug)
Found: Undocumented ECOMPILE option: -ri [dir]
Same as '-r' except it recursively compiles .INC files! Useful for
testing that your include files compile!
Fixed: ECOMPILE options bug: -r [dir] / -ri [dir]
These options will no longer 'eat up' options that follow them on the
command line ("-r -u" would incorrectly 'eat' the "-u" option!). Such
an option would be equivalent to "-r . -u" (recurse current folder).
NOTE: If you need to compile files AS WELL AS recursing the current folder
you MUST add the '.' (no quotes) so it doesn't treat the files as a
folder (WRONG one would try to recurse the FOLDER 'myscript.src'!)
This is WRONG: ECOMPILE.EXE -u -r myscript.src
This is RIGHT: ECOMPILE.EXE -u -r . myscript.src <-- note the '.'
The compiler will now put correct function names in listfiles.
ECompile now displays "deprecation" warnings for certain operators and tokens and
although your scripts will still compile, these are now "last warnings":
- '=' is deprecated; use '=='
- 'local', 'global' and 'dim' are deprecated; use 'var'
- 'begin' and 'end' are deprecated.
** Deprecated expressions will be removed from 096 **
** so make sure you update your scripts!!! **
Updated ECOMPILE and RUNECL banners to include better version info
(number after the decimal point is the supported file version)
Fixed a nasty compiler error. Expressions like this:
(!ev.source.isA(POLCLASS_NPC))
will now work properly.
The compiler used to consider that something like
(!ev.("source".isA(POLCLASS_NPC) ) )
Fixed: compiler bug w/ switch statement containing variable declarations
Fixed: compiler bug allowing this to compile:
Broadcast( "ff";
Fixed an ecompile error with substrings/multidimensional subscript access ( ex: tmp := Props[3,1] )
Added support for ecompile.cfg and packaged includes
see scripts/ecompile.cfg.example
usage: include ":pkgname:filebase";
New ecompile.cfg options:
GenerateListing [0,1]
GenerateDebugInfo [0,1]
GenerateDebugTextInfo [0,1]
ecompile: uses ECOMPILE_CFG_PATH environment variable to find ecompile.cfg, if present.
(note that normally it tries to look where the executable is. Some shells don't always pass this,
particularly if you're using batch files or shell scripts - try putting the full path to ecompile in your batch file)
Added a bewildering number of options to ecompile.cfg:
DisplayWarnings = 0/1 (same as -w flag)
CompileAspPages = 0/1 (same as -a flag)
OnlyCompileUpdatedScripts = 0/1 (same as -u flag)
GenerateDependencyInfo = 0/1 Generate .dep files whether or not updating
DisplayUpToDateScripts = 0/1 Display the "xxx/script.ecl is up-to-date" message, or not.
AutoCompileByDefault = 0/1 If set, and you don't pass any script names or -r or -A, will perform an auto compile.
UpdateOnlyOnAutoCompile = 0/1 If set, autocompile will only update modified scripts.
DisplaySummary = 0/1 Displays overall totals after compilation, unless compilation aborted due to a compile error.
Client Compatibility Changes
Changed: Removed client 2.0.* weather packet disable. Let us know if there are still weather problems with
2.0.* clients.
Clients tested up to 4.0.0e (4.0.0e and newer do not like the uoclient.cfg setting EnableControlFlowPackets enabled,
and causes login to fail.)
Fixed the map Z-height algorithm to match the UO client for negative Z
(for an example, see 1906,49)
Fixed: core now sends correct number-of-chars to client at login (this should fix the UOTD
"can't create character" client issues)
Added: Implimented new encryption routines as the basis for making future encryption updates
a LOT easier (and is the start of internal support for encryptions 2.0.3 upwards!)
Fixed legacy v1.xx-client 0x33 pause/restart packet padding.
Still works for "mass item/multi update" though, to help with blackholing.
See TotalStatsAtCreation in SERVSPECOPT(.LOCAL).CFG for "Total stats sum to 80" Problem under 094.
Removed unecessary equip layer check (some items in client 4.0.0 were prevented from being equipped due to
a client bug).
Max SkillID configurable in uoclient.cfg.
Added ClientEncryptionVersion "none" and "uorice" to help newbies. These are identical to "ignition".
Movement Changes
Frozen/Paralyzed ghosts are no longer able to move due to being dead.
New player privilage: 'freemove' - ignore Pushthrough/stamina cost for movement
Fixed: Characters with the "freemove" privilages can now move with 0 stamina, frozen,
or paralyzed.
New syshook for walking through other players (note, takes alot of CPU)
i.e. define a package with syshook.cfg :
SystemHookScript pushhook.ecl
{
Pushthrough Pushthrough
}
with pushthrough.src with something like:
use uo;
program PushthroughHook()
return 1;
endprogram
exported function Pushthrough(walker, obstructors) //note passed ARRAY of mobiles in destination tile
//including hidden mobiles
foreach mob in obstructors
print(mob.name);
endforeach
if(GetVital(walker,"Stamina") < GetVitalMaximumValue(walker,"Stamina"))
return 0;
else
return ConsumeVital(walker,"Stamina",1000);
endif
endfunction
Added: "You are too fatigued to move" message when trying to move with 0 stamina, or
not enough stamina as defined in movecost.cfg. (Only if MovementUsesStamina=1 is
enabled in servspecopt.cfg)
NPC Changes
Added: Newly created NPCs send and receive SYSEVENT_ENTERED_AREA events with the NPCs around them.
New member for the Text Event struct: "texttype". This will be a string with a value of "yell",
"whisper", "emote", or "default" depending on the type of speech received.
NPCs will only receive text events if the source is in range, depending on the texttype (this
will be configurable in the future, for now, whisper is 2 tiles, normal is 12, and yell is
25 tiles). So an NPC will not get a yell event from a source 30 tiles away, even if its
speech event range is 40. Item text listeners will get all text in their range, regardless
of texttype. (Need feedback for this)
The npc.em movement functions (Wander(), Move(), WalkToward(), WalkAwayFrom(), RunToward(),
RunAwayFrom(), TurnToward(), TurnAwayFrom(), WalkTowardLocation(),WalkAwayFromLocation(),
RunTowardLocation(), RunAwayFromLocation(), TurnTowardLocation(), TurnAwayFromLocation())
now return 1 is the move was successful, and 0 if the move failed. NOTE this will almost
ALWAYS return 1, if UseAdjustments is true (see next item), because the "adjusted" move
probably succeeded.
New npcdesc.cfg member: UseAdjustments : If set to 1 all NPCs of this template will behave as
normal when blocked by and object (pace back and forth if path is blocked). If set to 0, the
NPC will not attempt to find a adjacent tile toward the target that is not blocked (defaults
to 1 if not found in the npcdesc.cfg entry). Also, a new NPC member with the name
".use_adjustments" is read/write. These NPC changes are in preperation for a pathfinding
system.
New npcdesc.cfg member: RunSpeed . If present, (default to dexterity value) this value is used
for time delay between NPC moves (maximum usable value is 250, which is pretty damn fast!
Running NPCs move twice as fast as walking NPCs). Also, a new NPC member with the name
".run_speed" is read/write.
Map Object Changes:
You finally can now plot courses on maps. Here's the interface:
New property for itemdesc.cfg Map{} entries: Editable, which defaults to 0
This determines if the user can plot points on the map gump. Note you can still edit the map
via the script methods.
New script methods for map objects:
GetPins(): returns an array of structs with .x and .y members for each pin point.
InsertPin( index, x, y ): inserts a pin with the passed x,y before the passed index. Valid range 0 to n-1
AppendPin( x, y ): appends a pin to the end of the course with the passed x,y
ErasePin( index ): erases the pin at the passed index (valid 0 to n-1), and shifts pins down.
isa(): returns true if the object is a map object
Debugging Changes:
Added: POL now supports Minidumps on Windows. If you are running POL on Windows XP, you do not need to do
anything to enable this. Before Windows XP, you need a new "dbghelp.dll" with version 5.1 or greater in your
POL directory. This should be included in the final 095 core package.
What Minidumps do: When(/if!) POL crashes, you will no longer see the cryptic dump of registers and call
stack. Instead, POL will log and print on console that it has created a ".dmp" file in your POL directory.
This file is much much more useful to us for debugging a crash than the simple text dump as before. This
File should be sent to the developers along with the usual "what I did to cause this crash" information.
If you run Linux, everything should work as before.
Logging Changes:
accounts.txt reading info, X elements in Y ms.
Log additions: character creation, deletion
pol.log will now roll over every day. Old logfiles will have names of the form: pol-YYYY-MM-DD.log
Added: character and account name to "No handler for skill X" message.
Added: IP & Account logging information for unexpected and out-of-sequence messages.
Added:The originally defining package will be listed when multiple packages define an objtype
Changed: "attack timer" spam outputs only when DebugLevel >= 20
For debugging: leftovers.txt is written to the pol directory on shutdown, contains serial and name for
objects that survived cleanup somehow.
Misc Fixes
Changing an item's graphic will also set its height accordingly.
Mobiles will now break off an attack when an opponent changes from non-Innocent to Innocent.
(previously, this happened for PCs, but not for NPCs, particularly pets)
Fixed: Dead NPC taking damage somehow is now killed.
Fixed: Deleting an element from the datastore will mark the associated file as dirty.
Fixed: A Mobile's lifebar will no longer disappear when you (for example), poison it.
Fixed: If zero items were sold to an NPC, a gold coin was created in the player's pack with
amount == 0.
Fixed: If the items sold TO an NPC merchant cost more than 60k gold, the core now creates seperate
stacks of 60k gold instead of one greater than 60k (invalid for the client). So if you have any
script code that handles this, you should probably remove it (or face creating twice the amount
of gold you should!).
Fixed: Warmode ghosts are no longer flagged criminal/aggressor for dbl-clicking on mobs/PCs
Fixed: While on a moving boat, mobile's names no longer flash, and it's much easier to talk on a moving
boat. Only annoyance is now mobiles show the walk animation while the boat moves (but don't move anywhere)
Fixed: offline boat travelers were not being processed correctly on startup, leaving them behind on the water.
Implimented Serial Recycling:
When POL reaches the maximum serial for characters (0x3FFFFFFF) and items (0x7FFFFFFF), it will then
search from the minimum serial (1 for characters, 0x40000000 for items) for an unused serial to give.
Note, nothing is done about CProps which store serials referring to destroyed objects. Hopefully with
this system of reusing the "oldest" unused serial will avoid most of these problems.e.
Misc Changes:
Changed: These Item creation/movement/deletion functions now properly will update character's weight on
the status gump: ConsumeSubstance, DestroyItem, CreateItemInContainer, CreateItemInBackpack,
MoveItemToContainer, MoveItemToLocation, SubtractAmount.
Changed: Sound effect support updated: repeat/single-use, volume and 'z' variables noted.
Changed: renaming a stackable item a specific name will now prepend the amount to the single-click description.
i.e. rename 2 items 'sucky item', then stack will produce a desc of '2 sucky items'.
See more files for this project here