RSS

“skin assist” mod project

a few days ago ,one admin added a skin to my server and accidentally wiped the entire list of server packages out of the ini.( why is there a “empty” button with no conformation? WTF smirf.

i have been live editing the server ALOT latly , infact the uptime was easily  3 weeks, with only serverpackage edits live on server. and i added quite a few packages in that time.

To minimize downtime , without having a recent ini backup , ( many recent edits) i opened up the last non locked server log and recreated the server packages based on package load info ( yeah for bob saving the day)
btw that the difference about me and the next guy, I try to know how to work myself out of the corner that i get shoved into, by thinking.

unfortunately , that log was slightly old , and without shutting down the server to get the new data from the log ( and kick everyone off) i did temporally miss a few recent server packages like skins and some extra weapons we were testing.

so how did i find that out ?
Someone asked where there skin was not on the server anymore!

as a joke in annoyance , i said that i was going to make a system that does it automatically, or just bans every one with a custom skin.

After thinking about the issue , and some experience i gained working on that essential mutator i wrote .I realized that not only was a server side skin manager possible , but could have some bonus features.

so what the heck is skin assist?
It Is a mutator , what it does  is saves the player login information at join , then process it after a player joins, analyzing weather the skin is is the server packages. if it is in the server packages , it does nothing, the skin works like it would normally on any server.

if the desired skin is not in the server packages , it searches all files on the server to see if the skin utx files is available to load/install.

If the file is on the server , it is added to a custom list of on demand skins.
along with the requesting player , and add date. upon the level switch , the mod automatically adds these skins files to the server packages ready for use by the player,this list is separate from the normal server packages.

if the file is not on the server, the user is prompted to contact the admin , or in my case – (in the future )they are directed to a php page where they can upload there skin utx file to the server.This could potentially present some security issues latter on but ill probably address those with package content analyses (texture only content within package). The skin file they request  is also added into a list in the ini file , so that a admin can manually see what skins players want to use and add them accordingly.

the mod could be modified allow skins to expire to reduce server packages. if a players dont visit the server in 90 days the skin could be automatically removed from the server packages , to reduce downloads. rejoining the server by the player can reset the count.

but there is something feature even way more clever.
We have there prelogin information that tells the server there skin   request.  if they are already on the server , and they reconnect, we can match the player name , ip , and join parameters to a player already on the server. This way is a player is on the server , and want to change there skin for any reason, they would normally have to reconnect, lose there place and inventory. ….. or will they?

my mod matches the login details  ,Does some comparison for class/skin changes, and if the player class is the same , But the skin parameter changes , it rejects the request to join, and takes there requested skin and changes the players skin while still ingame.

this wont work with as is with skins not in the server packages ( but we can address  that like we do normally, by checking the server and adding them on demand)
so what we has here is fast skin changing. people can change and test skins all day long without having to fully rejoin the server,
in the cases where the class changes , it will force a reconnect.
in the case of the requested skin not in server , it can reject the reconnect and warn the user.

There is still some bugs to work out and features to add.
for instance, if you change your skin many times , it changes from original join skin to current selection , so rejoining with your original join skin , forces a reconnect.also in seemingly random cases , it cant detect skin at all. , and gives error “” as skin , some error in my code i am sure.
over 700 lines of code that i need to review to do this , lol

there will likly be in game admin commands to register/ remove skins from the package, and well as list skins uses etc
there will be command to attempt to get all skins avalible on server , so far only lists actively loaded skins tho. and a skinswitchcommand to manaully switch to skins you dont have installed.( temporarily , or by join url)

a custom verision will be created to  address  names while using monsterplayers. in current  , you can play on my servers as the monsters , using the monsternames , but this mod in future will after you join , will join as the playername you use before reconnect.

well well , hope you are excited.  needed some encouragement  via interest to bug fix things.

Advertisements
 
1 Comment

Posted by on December 4, 2015 in Uncategorized

 

T3d Patch maker demo

I made this tool a few years back in a less finished form .
it is for placing specific items in editor , for spawning in a mutator

Download
http://bobisunreal.com/publicfacingfiles/Tools/t3d%20patchmaker%20beta.exe

Instructions
– Place “unique” actors in unrealed.
– Strip bsp  , then export as t3d
– Open t3d in tool
– Tell it your “unique” actor short name (case sensitive)
– Tell it what to spawn in its place.
– Tell it a filename to save the source to
– Enjoy ready to integrate unrealscript.

Outputed script  looks like this:

if(Level.Title ==”Rrajigar Mine “)
{
actNewClass = class<actor>( DynamicLoadObject(“present1.Greeng”, class’Class’ ) );
actthing=Spawn(actNewClass,,,vect(-333.910217,443.582031,-54.000000));
actthing=Spawn(actNewClass,,,vect(2080.291016,1049.140991,138.000000));
};

Known Issues
– Somtimes breaks phrasing completly for some actors.
– Tool cant handle t3d files over a few mb (hence strip bsp first)
– Rotation is not  supported..

it some future world , this tool can likey be Totally written in Unrealscript , or as ucc commandlet, and not a exe.
log(); can be abused to export the code maybe

ill give lua source as some future edit

 
Leave a comment

Posted by on October 20, 2015 in Uncategorized

 

Design notes #1 – Detecting Abrupt Restarts

Theres are  few mods avalilable that can go back to a map after server goes down,
most notably it is built into jcoopz1 , and in the mod dzmapmutator.
both closed source mods.

A while back somone asked if you could detect if the server was told to close , or closed unexpectadly.
Some of use talked back and forth and discussed how dzmapmutator probably handles the situation,
dots provided this simple example of detecting the situation by adding a extra paramenter to the traveling url of the server.

—————————————————————————-

local string S;

S = Level.GetLocalURL();

if (InStr(S,”?restarted=true”)!=-1)
{
// already changed our url
}else{
Level.ServerTravel(ReplaceStr(s, “0.0.0.0/”, “”)$”?restarted=true”,false);
}

—————————————————————————-

What it does is basicly check to see if  a paramenter is present in the servers url , and if it is not ,
we re-navigate to the map addign the argument.

Pretty cool huh?

Knowing this  we can have the server resume at the map that we left off at when the server went down,
This is generally desirable , for the sake of mappacks, or servers with a set map rotation.

to do this we just need to need to store the last map that was loaded.
we can also save the uptime as well

——————————————————————

var config() string crashmap;
var config() int uptime;

local string S;
S = Level.GetLocalURL();
if (InStr(S,”?restarted=true”)!=-1)
{ // already changed our url
crashmap = string(level.outer); // save te3 level to config
uptime ++;
}else{
if  (crashmap ==””) // incase of no stored map
{
Level.ServerTravel(ReplaceStr(s, “0.0.0.0/”, “”)$”?restarted=true”,false);
}else{
Level.ServerTravel(crashmap $”?restarted=true”,false);
}
}

——————————————————————–

What this will do when the server starts , It checks if the paramenter is stored in the url ,
if it is not it then checks to see if we had a last map we were at stored ,
if not the map reloads with the peramaters.if it has a saved map stored , it travels to the last map that was loaded.

Thats the standard way its handled, But what about the crash itself ?
how do we detect if the server was shutdown vs the server exiting improperly?
is it even possible?

sort of.But we need a but of help from outside the game tho.

unreal.exe creates running.ini while the game is running.
if the game abruptly  closes ( gpf  etc) usally this file is not cleaned up.

If you use a batch file to Launch your server, it can easily be modified to detect this remnant.

This is a example batch file that can detect the running.ini at launch

@echo off
rem cls
:restart
if exist running.ini (
echo Abrupt restart!
unreal.exe server SpireVillage.unr?Game=JCoopZ1.JCoopZGame?crash=true Difficulty=3 ini=unreal.ini -timestamplog -server
goto Restart
) else (
echo Server Started Normally
unreal.exe server SpireVillage.unr?Game=JCoopZ1.JCoopZGame?crash=false Difficulty=3 ini=unreal.ini -timestamplog -server
goto Restart
)

We use the existance of the running.ini to detect there was a fault, then  pass that paramenter to the game in the commandline,
so we can be later used in   unrealscript.

the Code to detect the crash in game is very similar to the returntocrashmap code above.

———————————————————————————–

local string S;
local bool serverabrupt;

S = Level.GetLocalURL();

if( InStr(S,”?crash=true”)!=-1 )   // Running.ini was present at launch
{
// abrupt start.

}else{
//non crash start

}
————————————————————————————-

They can both be combined with  some extra bools.
This detects clean exit vs aburt exit, and also when the server goes down for any normal reason,
will resume  where it left off.

————————————————————————————
var config() string crashmap;
var config() int uptime;

local string S;
local bool serverabrupt;

S = Level.GetLocalURL();

if( InStr(S,”?crash=true”)!=-1 )   // Running.ini was present at launch
{

// abrupt start.
serverabrupt = true; this flag is set every map switch  , so any mod can detect it.
if (InStr(S,”?restarted=true”)!=-1)
{ // already changed our url
crashmap = string(level.outer); // save the level to config
log(“saving crash map…”);
uptime ++;
}else{
uptime=0;
if  (crashmap ==””) // Incase of no stored map
{
log(“abrupt crash with No saved crash map… reloading level”);
Level.ServerTravel(ReplaceStr(s, “0.0.0.0/”, “”)$”?restarted=true”,false);
}else{
log(“aburt crash . loading saved crashmap..”);
Level.ServerTravel(crashmap $”?restarted=true”,false);
}
}

}else{
//non crash start

serverabrupt = false; this flag is set every map switch  , so any mod can detect it.
if (InStr(S,”?restarted=true”)!=-1)
{ // already changed our url
crashmap = string(level.outer); // save the level to config
uptime ++;
log(“saving crash map…”);
}else{
uptime=0;
if  (crashmap ==””) // Incase of no stored map
{
log(“First run ! restart with No saved crash map… reloading level”);
Level.ServerTravel(ReplaceStr(s, “0.0.0.0/”, “”)$”?restarted=true”,false);
}else{
log(“first run!. loading saved crashmap..”);
Level.ServerTravel(crashmap $”?restarted=true”,false);
}
}

}
———————————————————————————————

Uptime stats saved in uptime int, it’s reset ever time a serverstart occurs,
also saves serverabrupt bool to note of a abrupt start.

In the rare case of a map that could pottentaily crash repeatady ,

one can try add repeat crash detection.
not exactly sure how one would know to breakout.
we could keep rack of the last crashed map ( technicly we already know the last map).
and keep a tally of how many times it close improperly .

so I came up with this even better mess.
– Detects crash / vs normal start
– Keeps stats of every level that the server crashed on, ever.
– Resumes the last map if it never crashed more then 5 times before.

– important note : code below untested , writtin in notepad.

———————————————————————————————————-

var config() int crashtimes;
var config() string crashmap;
var config() int uptime;

struct maperrors()
{
var string map;
var int crashes;

}

var config() maperrors mapcrashstats[255];
var string S;
var bool serverabrupt;
var int returnvaltemp;

function int trackmapstats(string map,optional bool incement)
{
//lookup a saved map data. return a count
//if its not here add it and return 1
//if you use bool arg “incement” add one to the count for our match when we do the lookup.

local int bc,foundline;
local bool bfound;

For( bc = 0; bc <  255 ; bc++ )
{
if (mapcrashstats.map !=”” && mapcrashstats.map == map)
{
//found map saved
foundline = bc;
bfound = true;

if (incement)
{
mapcrashstats.crashes ++;
saveconfig();
return mapcrashstats.crashes;
}else{
saveconfig();
return mapcrashstats.crashes;

}

}
}

if (!bfound)
{

For( bc = 0; bc <  255 ; bc++ )
{
if (mapcrashstats.map ==”” && !bfound)
{
//open slot
mapcrashstats.map= map;
foundline = bc;
bfound = true;
mapcrashstats.crashes ++; // add out first
saveconfig();
return mapcrashstats.crashes; // break out
}

}
}

}//!found

}

=========================================================================================
// on mutator startup / init / prebeginplay

if( InStr(S,”?crash=true”)!=-1 )   // Running.ini was present at launch
{

// abrupt start.
serverabrupt = true; this flag is set every map switch  , so any mod can detect it.
returnvaltemp = trackmapstats(string(level.outer),true); // lookup or store the map stats
// save  the stats for the last crashed map. , only save at first start.
log (“This map has Crashed ” $ returnvaltemp $  ” timees  in the past”,’Warning’);

if (InStr(S,”?restarted=true”)!=-1)
{ // already changed our url
crashmap = string(level.outer); // save the level to config
log(“saving crash map…”);
uptime ++;
}else{
uptime=0;
if  (crashmap ==”” || returnvaltemp > 5) // Incase of no stored map OR map crashed to many times
{
if (returnvaltemp > 5)
{
log(“Previously loaded map encountered to many crashes… reloading level”);
}else{
log(“abrupt crash with No saved crash map… reloading level”);
}

Level.ServerTravel(ReplaceStr(s, “0.0.0.0/”, “”)$”?restarted=true”,false);
}else{
log(“aburt crash . loading saved crashmap..”);
Level.ServerTravel(crashmap $”?restarted=true”,false);
}
}

}else{
//non crash start

serverabrupt = false; this flag is set every map switch  , so any mod can detect it.
if (InStr(S,”?restarted=true”)!=-1)
{ // already changed our url
crashmap = string(level.outer); // save the level to config
uptime ++;
log(“saving crash map…”);
}else{
uptime=0;
if  (crashmap ==””) // Incase of no stored map
{
log(“First run ! restart with No saved crash map… reloading level”);
Level.ServerTravel(ReplaceStr(s, “0.0.0.0/”, “”)$”?restarted=true”,false);
}else{
log(“first run!. loading saved crashmap..”);
Level.ServerTravel(crashmap $”?restarted=true”,false);
}
}

}

—————————————————————————————————-
so i guess that adreesses everyones concerns. lol

 
5 Comments

Posted by on October 12, 2015 in Uncategorized

 

data caching ideas

Hopefully the files here are all back in order , they probably were hours after i posted anyway.;D

Anyway nothing is happening the only thing i barely did lately for unreal is
start building a caching system for the db system i created for my mods.
the ini database itself was a very clever idea but after quite a bit of data( 3000 lines for me )
It got to the point where every time you shot something , It would lag due to read/search/write.

someone recommended building a hash table , but due to the Dynamic RAD design of the  database,
You cant just create references , and while for example a number compare is 5x faster then a string compare,
The database is totaly writen in stings , that can be number of types. also unreal doesnt provide a hashing fuction for string 2 md5 etc
so in general a hash table would be way more work then its worth i think.

so we think about the problem.
searching 3000 lines to do a lookup is bad.
searching 3000 lines to modify the matching value is bad.
Writing to the ini every time somone moves , also bad.

whats not bad?
read/write for small lists.

So the plan?
cache the stuff we need , mostly JIT as we need it.

Need a value? Do a lookup of the value in the database and copy it to a struct in ram.
next time you look up the value , its has been cached , so you need to only search the cache ( witch at this point is 1 row long.)
In some cases such as int , or a bit toggle , we have no reason to even get the value from the db , we can write straight to cache.

Not all data needs to be searched or  even passed over now, only relevant rows.
if a player joins the server,maybe some of there data is loaded, like login  account info ,
as things are killed relevant class data can be cached , or even the map is analyzed for killable classes and those are cached.
new unknowns a re ammended to the cache etc.

in a case like this the other 2999 rows  related to players that are not online. in the original system that data is iliterated EVERY time we do a lookup or edit.

In this system it looked up a limited number of times and cached.

at the end of the level its merged back to the ini based database when game play it irrelevant, this single write could take 3 secends maybe , but none would see it.

But hey what if the server goes down half way tho the map bro?
The cached data gets lost.yep it sucks
Writes could be written every so often , or anytime all players leave etc

for values that must change , like account info or somthing , the modify data function will provide a optional forcewrite bool.

2015-09-10 23-41-45 Screenshot

anyhow i only wrote like 4 of the  dozens of functions required to built this yet , because i don’t see the potential return of my time atm.

 
Leave a comment

Posted by on September 11, 2015 in Uncategorized

 

Stuffs getting maintenanced’ and upgraded.

We bought the domain (using local webspace)
at http://bobisunreal.com/

all sites are staying where they are tho , gonna use it as a hub.

I am Redoing all files storage to do with everything unreal related.
and While unrelated  To most here i am reorganizing my massive collection of unreal files,
To make sure i have everything in one place i moved all the files i had on dropbox into my archive
( which is symbolically linked to a  webserver atm) Since some thing where in one place and not archived.

so 99% of unreal dropbox files on this blog , and the http://bobscoop.comyr.com/   site are now broken.

My plan is to redo the comyr page as what it was , But I plan of linking to a webserver for the small files , and mirroring them on either dropbox or the comyr site that i dont currently utilize,  files.bobscoop.comyr.com ,
haven’t decided , but i am rewriting the project pages  regardless.

In the interim i am rebuilding The projects page on the webserver to utilize the domain. But since that page is down while the webserver is down , i dont want that to be the primary website.[also it cant be].

Anyway , if you need files  that where on the blog or websites , You just Gotta ask for the time being, I am sure noone wants my shit anyway

 

 
2 Comments

Posted by on July 31, 2015 in Uncategorized

 

Interaction Tutorial.

There are many ways to address the topic of having the user control something( specificity script code).

User Input / Interaction Methods

  • Methods
    – Replication
    – Binding keys
    – Chat scanning
    – Checking keystrokes
    – Pick-up Activation/Deactivation
    – Triggers
    – Fake Weapons

Some of these methods have advantages and disadvantages , and different usage scenarios.
Like most things in unreal script Not every method is ideal for each application , most anything can be made to work.

Replication
The most common method for interaction in uscript is using replication – Role<ROLE_Authority to replicate exec functions,
This is what is used for most of the commands in unreal such as FLY , SUMMON , etc. This allows you to catch things typed into the console.

Example Code
—————–
class commandsthing expands pickup;

Replication(
reliable if( Role<ROLE_Authority )
dothat;
}

exec function dothat(){PlayerPawn(Owner).ClientMessage(” some action”);}
—————-

This method requires your code class to be placed on a client package / actor ,
Mostly always thats a pickup/item/weapon (or declared in the playerpawn)
in the case of playerpawn , It’s self replicated without Replication declaration.
it isn’t usually usable in any other classes , and this method has the advantage that you can have required arguments
so for instance dothat( int mynumber) will only accept a # and that argument will be passed straight to your functions,
Without having to phrase anything yourself.

The downsides are that the client has to have downloaded this class. it cant be “hidden” like server side code, also replicating
tons of commands probably isnt good for the server ( you can get RPC overflows – But you would have to replicate hundreds of things for that to happen)
also your code is executed on the pickup or class , Or course you can pass instruction elsewhere or obfuscate ( for instance for login commands),Using blind dummy dynamicloads and child classes.
In general this is the accepted method for adding commands to a game.

Additional you can use mods to rebind the clients keys to call one of these replicated commands.FE how voting handler overides or amends your X key.

Chat Scanning
Chat scanning is sort or common function of modern games – whether your notice it or not. mine craft and gtaSA and many games use it,
As far as unreal227 is concerned , its a passive method – A simple mutator can sit and wait for chat callbacks.
all chat goes tho the system as usual – If a magic string such as “/” or “/togglechat” is seen in a chat message the chat is phrased and you can execute a action based on that.

If your sever/game version is < 227 you can use a dummy pawn actor to listen for chat strings , but you wont be able to not show them in the chat,Its possible but alot more inconvenient to get who chated what.

The main advantage to this is that is entirely serverside , So you can put security related stuff ,
and link/references to other packages that are linked to dlls etc , The client never has to download it.
so you can be clever and unload/rebuild/update the commands mod without shuttingdown/restarting your server.
The downsides to this method is that you need to phrase the chat yourself if you want more then a simple executed action.
If you want arguments you need to intelligently process the data , Breaking up space delimited text and converting strings to numbers etc ,also you need to do alot of idiot checking for spaces , bad args, or args out of sequence.

The other downside is that everyone was trained to NOT type commands into chat , but the console!
So unless you explain how it works , most people wont understant why is doent work.

Some example code here:
http://www.oldunreal.com/cgi-bin/yabb2/YaBB.pl?num=1409617108/0#0

Checking keystrokes
While I cant give a elaborate example , Ill point out that 227 has the ability to detect key presses.
Is is necessary to do this ON THE CLIENTSIDE. and you must check if a button is pressed/held , In some tick/timer etc.
You must create your own debouncing scheme and then or course execute your functions.
A check like this would work good in HUD classes inside postrender etc.

use a table like this http://www.dakmm.com/?p=272 ,

you can make a uscript comparison table array if your clever. think array(KEYCODE) = array.charstring to mass check keys.

if (PlayerPawn(Owner).IsPressing(32))
{

}
If your clever you can check for every possible key clientside , and pass that data blindly back to the server for post processing
in a single sting FE “a6-=” etc then phrase it sever side.
I also may suggest that is possible to write a crude keylogger this way(Viewport keystokes only , Dont get excited!).

Pick-up Activation/Deactivation/use
For some simple action (fly mods/skin swaps etc), You could toggle on/off by the states of a pickup, of even be creative and foreach/item and
detect active states as a easteregg. This type of thing is intuitive and easy to understand for any player.
You can even set up multiple pickups to build a navigation system menu type thing – Think 5 items (up / down/ left/right/enter) Thats sort of insane tho.
But if your already doing this why dont you just go ahead and replicate some functions to get calls from the console?????

 Triggers-
This is a convoluted method. mostly for map makers. You build a room in the map that has triggers that execute your code. You can use this method
in a server context by spawning visible sprite triggers with a serverside mod, FE triggers at the beginging of level that change your model or affect
the player , execute some scripted code etc.

Fake Weapons
You use a fake weapon to interact with the players fire/altfire binds ,
Prehaps even use/ overide next/prev weapon actions. The bonus here is that you have callbacks easily available to the hud to draw stuff.
Think right click shuffles , left click selects.

(to be continued … maybe?)

 
3 Comments

Posted by on July 25, 2015 in Uncategorized

 

goats!

semi usable  just for fun-
Download
https://yadi.sk/d/8a7OHcmEhPYF8

summon goat.mycow

ill make it into a goat player at some point if nobody beats me to it.

 
2 Comments

Posted by on July 2, 2015 in Uncategorized