Yksi kaveri sanoi, että täällä kannattaisi tätä kysyä. Elikkäs liero extreme pelissä voi tehdä omia asemodeja, jotka sitten skriptataan yhteen (tekstitiedostot) ohjelmalla nimeltä LXcompiler. Tuo tiedosto jonka se värkkää on .lgs päätteinen. Elikkä itse ajattelin että väsäisin näitä modeja, mutta aika kimuranttia on, joten ajattelin jos joku teistä voisi väsätä ohjelman (De-compiler) joka siis muuttaisi sen .lgs tiedoston takaisin niiksi alkuperäisiksi tekstitiedostoiksi. Oletko vielä kärryillä?
Käyttäisin sitä apuna omien modien tekemiseen, eli harjoittelisin niillä asetuksilla, yms. Kiitos jos joku jaksaa nähdä vaivaa sen suhteen.
Millasta tuntipalkkaa ajattelit?
Onko se niinkin vaikeaa.. Öh, ihan ilmaiseksi ajattelin.
no ellei joku putkalaisista ole itse ollut ohjelmoimassa Lieroa niin kyllä se aika vaikeeta on...
Auttaisikos se ohjelma millään lailla? Olen itse aika pihalla näistä hommista.
kyll se varmaan auttais, mutt jos ne pelintekijät ovat tehneet oman scripti kielen, niin sitä on aika vaikeeta lähtee purkamaan...
Okei. Elikäs luulen, että kukaan tuskin yrittääkään. No, ei voi sitten mitään..
Kyll joku saattaa yrittääkkin, en ole mikään kovin kummoinen ohjelmoija, joten jotkut paremmat ohjelmoijat saattavat osata/viitsiä tehdä sellaisen ohjelman...
Selvä.
Mitä nyt tuota katselin, niin pelin ja/tai compilerin tekijä varmaan nysväisi decompilerin tunnissa - parissa, mutta kun dokumentaatiota ei ole niin ulkopuoliselta menisi varmaankin moninkertainen aika, ja lopputulos ei välttämättä silti toimisi 100%.
Voihan tuon joku ottaa haasteena ja tehdäkin :D Itsellä riittää haasteita joista maksetaan palkkaakin, niin ei voi liikaa ottaa hupiprojekteja.
Lataat sorsat ( http://openlierox.sourceforge.net/ ) ja katsot miten se taikoo näitä tiedostoja?
oho, en huomannutkaan että tuosta oli open source versio.
löysin sen koodin, millä se scripti käännetään, mutta en oikeen ymmärrä sitä, koska olen niin huono ohjelmoimaan... :(
No jos laitat sen koodin tänne ja joku muu jos voisi sen tehdä, jos riittää aikaa. :/
okei, tässä tulee, mutta en kyllä ole 100% varma, että onko juuri tämä se koodi...
No jos on väärä joku saa poistaa sen...
Tuossa osa siitä tiedoston sisällöstä, voin postata loputkin jos joku tarvii...
int CGameScript::Save(const std::string& filename) { FILE *fp; int n; // Open it fp = OpenGameFile(filename,"wb"); if(fp == NULL) { printf("Error: Could not open %s for writing\n",filename.c_str()); return false; } Header.Version = GS_VERSION; strcpy(Header.ID,"Liero Game Script"); // Header gs_header_t tmpheader = Header; EndianSwap(tmpheader.Version); fwrite(&tmpheader,sizeof(gs_header_t),1,fp); fwrite(GetEndianSwapped(NumWeapons),sizeof(int),1,fp); // Weapons weapon_t *wpn = Weapons; for(n=0;n<NumWeapons;n++,wpn++) { writeString(wpn->Name, fp); fwrite(GetEndianSwapped(wpn->Type), sizeof(int), 1, fp); // Special if(wpn->Type == WPN_SPECIAL) { fwrite(GetEndianSwapped(wpn->Special), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->tSpecial), sizeof(gs_special_t), 1, fp); // WARNING: this works, because it contains only one int fwrite(GetEndianSwapped(wpn->Recharge), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->Drain), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->ROF), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->LaserSight),sizeof(int), 1, fp); } // Beam if(wpn->Type == WPN_BEAM) { fwrite(GetEndianSwapped(wpn->Recoil), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Recharge), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->Drain), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->ROF), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->LaserSight),sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Bm_Colour[0]), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Bm_Colour[1]), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Bm_Colour[2]), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Bm_Damage), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Bm_PlyDamage), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Bm_Length), sizeof(int), 1, fp); } // Projectile if(wpn->Type == WPN_PROJECTILE) { fwrite(GetEndianSwapped(wpn->Class), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Recoil), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->Recharge), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->Drain), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->ROF), sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->ProjSpeed), sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->ProjSpeedVar),sizeof(float),1, fp); fwrite(GetEndianSwapped(wpn->ProjSpread),sizeof(float), 1, fp); fwrite(GetEndianSwapped(wpn->ProjAmount),sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->LaserSight),sizeof(int), 1, fp); fwrite(GetEndianSwapped(wpn->UseSound), sizeof(int), 1, fp); if(wpn->UseSound) writeString(wpn->SndFilename, fp); // Recursively save the projectile id's SaveProjectile(wpn->Projectile,fp); } } // Extra stuff // Ninja Rope fwrite(GetEndianSwapped(RopeLength),sizeof(int),1,fp); fwrite(GetEndianSwapped(RestLength),sizeof(int),1,fp); fwrite(GetEndianSwapped(Strength),sizeof(float),1,fp); // Worm gs_worm_t tmpworm = Worm; EndianSwap(tmpworm.AngleSpeed); EndianSwap(tmpworm.GroundSpeed); EndianSwap(tmpworm.AirSpeed); EndianSwap(tmpworm.Gravity); EndianSwap(tmpworm.JumpForce); EndianSwap(tmpworm.AirFriction); EndianSwap(tmpworm.GroundFriction); fwrite(&tmpworm, sizeof(gs_worm_t), 1, fp); fclose(fp); return true; } /////////////////// // Save a projectile int CGameScript::SaveProjectile(proj_t *proj, FILE *fp) { if(!proj) return false; fwrite(GetEndianSwapped(proj->Type), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Timer_Time), sizeof(float),1,fp); fwrite(GetEndianSwapped(proj->Timer_TimeVar),sizeof(float),1,fp); fwrite(GetEndianSwapped(proj->Trail), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->UseCustomGravity), sizeof(int), 1, fp); if(proj->UseCustomGravity) fwrite(GetEndianSwapped(proj->Gravity), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Dampening), sizeof(int), 1, fp); // Pixel type if(proj->Type == PRJ_PIXEL) { fwrite(GetEndianSwapped(proj->NumColours), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Colour1[0]), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Colour1[1]), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Colour1[2]), sizeof(int),1,fp); if(proj->NumColours == 2) { fwrite(GetEndianSwapped(proj->Colour2[0]), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Colour2[1]), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Colour2[2]), sizeof(int),1,fp); } } // Image type else if(proj->Type == PRJ_IMAGE) { writeString(proj->ImgFilename, fp); fwrite(GetEndianSwapped(proj->Rotating), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->RotIncrement), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->RotSpeed), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->UseAngle), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->UseSpecAngle),sizeof(int),1,fp); if(proj->UseAngle || proj->UseSpecAngle) fwrite(GetEndianSwapped(proj->AngleImages),sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Animating),sizeof(int),1,fp); if(proj->Animating) { fwrite(GetEndianSwapped(proj->AnimRate),sizeof(float),1,fp); fwrite(GetEndianSwapped(proj->AnimType),sizeof(int),1,fp); } } // // Hit // fwrite(GetEndianSwapped(proj->Hit_Type),sizeof(int),1,fp); // Hit::Explode if(proj->Hit_Type == PJ_EXPLODE) { fwrite(GetEndianSwapped(proj->Hit_Damage), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Hit_Projectiles), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Hit_UseSound), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Hit_Shake), sizeof(int),1,fp); if(proj->Hit_UseSound) writeString(proj->Hit_SndFilename, fp); } // Hit::Bounce if(proj->Hit_Type == PJ_BOUNCE) { fwrite(GetEndianSwapped(proj->Hit_BounceCoeff), sizeof(float), 1,fp); fwrite(GetEndianSwapped(proj->Hit_BounceExplode),sizeof(int), 1,fp); } // Hit::Carve if(proj->Hit_Type == PJ_CARVE) { fwrite(GetEndianSwapped(proj->Hit_Damage), sizeof(int),1,fp); } // // Timer // if(proj->Timer_Time > 0) { fwrite(GetEndianSwapped(proj->Timer_Type),sizeof(int),1,fp); if(proj->Timer_Type == PJ_EXPLODE) { fwrite(GetEndianSwapped(proj->Timer_Damage), sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Timer_Projectiles),sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->Timer_Shake),sizeof(int),1,fp); } } // // Player hit // fwrite(GetEndianSwapped(proj->PlyHit_Type),sizeof(int),1,fp); // PlyHit::Explode || PlyHit::Injure if(proj->PlyHit_Type == PJ_EXPLODE || proj->PlyHit_Type == PJ_INJURE) { fwrite(GetEndianSwapped(proj->PlyHit_Damage),sizeof(int),1,fp); fwrite(GetEndianSwapped(proj->PlyHit_Projectiles),sizeof(int),1,fp); } // PlyHit::Bounce if(proj->PlyHit_Type == PJ_BOUNCE) { fwrite(GetEndianSwapped(proj->PlyHit_BounceCoeff),sizeof(float),1,fp); } // // Explode // fwrite(GetEndianSwapped(proj->Exp_Type), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Exp_Damage), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Exp_Projectiles), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Exp_UseSound), sizeof(int), 1, fp); if(proj->Exp_UseSound) writeString(proj->Exp_SndFilename, fp); // // Touch // fwrite(GetEndianSwapped(proj->Tch_Type), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Tch_Damage), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Tch_Projectiles), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->Tch_UseSound), sizeof(int), 1, fp); if(proj->Tch_UseSound) writeString(proj->Tch_SndFilename, fp); if(proj->Timer_Projectiles || proj->Hit_Projectiles || proj->PlyHit_Projectiles || proj->Exp_Projectiles || proj->Tch_Projectiles) { fwrite(GetEndianSwapped(proj->ProjUseangle), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->ProjAngle), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->ProjAmount), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->ProjSpread), sizeof(float), 1, fp); fwrite(GetEndianSwapped(proj->ProjSpeed), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->ProjSpeedVar), sizeof(float), 1, fp); SaveProjectile(proj->Projectile,fp); } // Projectile trail if(proj->Trail == TRL_PROJECTILE) { fwrite(GetEndianSwapped(proj->PrjTrl_UsePrjVelocity), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->PrjTrl_Delay), sizeof(float), 1, fp); fwrite(GetEndianSwapped(proj->PrjTrl_Amount), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->PrjTrl_Speed), sizeof(int), 1, fp); fwrite(GetEndianSwapped(proj->PrjTrl_SpeedVar), sizeof(float), 1, fp); fwrite(GetEndianSwapped(proj->PrjTrl_Spread), sizeof(float), 1, fp); SaveProjectile(proj->PrjTrl_Proj, fp); } return true; }
Luulisin että tuo on se oikea, vaikken voikaan sanoa varmaksi. Vielä kun joku voisi tehdä siitä sen ohjelman tai jotakin.. :/
Sinun kannattaisi opetella ohjelmoimaan, niin voisit tehdä itse tällaiset jutut...
putkassa on hyvä c-kielen opas.
Eikö ketään jolla on tylsää viitsisi väsätä :'(
Ei näyttävästi... :(
Ei ainakaan tuo tietojen tallentamiseen vehkis91:n postaama koodi kovin monimutkaista ole. Kirjotellaan vaan arvoja tiedostoon hieman niitä muuttaen(funktio GetEndianSwapped), jotta niiden lataus on arvatenkin helpompaa.
Löytyykö tuolta jostain koodista myös jotain CGameScript::Open -metodia? Kai se peli myös niitä tiedostoja availee, eikä vain luo uusia.
PS. Ihme tsättäilyä ketjussa
tuossa:
/////////////////// // Load the game script from a file (game) int CGameScript::Load(const std::string& dir) { // Try cache first CGameScript *cached = cCache.GetMod(dir); if (cached != NULL) { CopyFrom(cached); return GSE_OK; } FILE *fp; int n; std::string filename = dir + "/script.lgs"; sDirectory = dir; // Open it fp = OpenGameFile(filename,"rb"); if(fp == NULL) { SetError("CGameScript::Load(): Could not load file " + filename); return GSE_FILE; } // Header fread(&Header,sizeof(gs_header_t),1,fp); EndianSwap(Header.Version); // for security fix_markend(Header.ID); fix_markend(Header.ModName); // Check ID if(strcmp(Header.ID,"Liero Game Script") != 0) { fclose(fp); SetError("CGameScript::Load(): Bad script id"); return GSE_BAD; } // Check version if(Header.Version != GS_VERSION) { fclose(fp); SetError("CGameScript::Load(): Bad script version"); return GSE_VERSION; } // Clear an old mod file modLog("Loading game mod file " + filename); //modLog(" ID = %s", Header.ID); //modLog(" Version = %i", Header.Version); fread(&NumWeapons,sizeof(int),1,fp); EndianSwap(NumWeapons); //modLog(" NumWeapons = %i", NumWeapons); // Do Allocations Weapons = new weapon_t[NumWeapons]; if(Weapons == NULL) { SetError("SGameScript::Load(): Out of memory"); return GSE_MEM; } // Weapons weapon_t *wpn; for(n=0;n<NumWeapons;n++) { wpn = &Weapons[n]; wpn->ID = n; wpn->Projectile = NULL; wpn->Name = readString(fp); fread(&wpn->Type, sizeof(int), 1,fp); EndianSwap(wpn->Type); // Special if(wpn->Type == WPN_SPECIAL) { fread(&wpn->Special, sizeof(int), 1, fp); EndianSwap(wpn->Special); fread(&wpn->tSpecial, sizeof(gs_special_t), 1, fp); EndianSwap(wpn->tSpecial.Thrust); fread(&wpn->Recharge, sizeof(float), 1, fp); EndianSwap(wpn->Recharge); fread(&wpn->Drain, sizeof(float), 1, fp); EndianSwap(wpn->Drain); fread(&wpn->ROF, sizeof(float), 1, fp); EndianSwap(wpn->ROF); fread(&wpn->LaserSight, sizeof(int), 1, fp); EndianSwap(wpn->LaserSight); } // Beam if(wpn->Type == WPN_BEAM) { fread(&wpn->Recoil, sizeof(int), 1, fp); EndianSwap(wpn->Recoil); fread(&wpn->Recharge, sizeof(float), 1, fp); EndianSwap(wpn->Recharge); fread(&wpn->Drain, sizeof(float), 1, fp); EndianSwap(wpn->Drain); fread(&wpn->ROF, sizeof(float), 1, fp); EndianSwap(wpn->ROF); fread(&wpn->LaserSight, sizeof(int), 1, fp); EndianSwap(wpn->LaserSight); fread(wpn->Bm_Colour, sizeof(int), 3, fp); EndianSwap(wpn->Bm_Colour[0]); EndianSwap(wpn->Bm_Colour[1]); EndianSwap(wpn->Bm_Colour[2]); fread(&wpn->Bm_Damage, sizeof(int), 1, fp); EndianSwap(wpn->Bm_Damage); fread(&wpn->Bm_PlyDamage, sizeof(int), 1, fp); EndianSwap(wpn->Bm_PlyDamage); fread(&wpn->Bm_Length, sizeof(int), 1, fp); EndianSwap(wpn->Bm_Length); } // Projectile if(wpn->Type == WPN_PROJECTILE) { fread(&wpn->Class,sizeof(int),1,fp); EndianSwap(wpn->Class); fread(&wpn->Recoil,sizeof(int),1,fp); EndianSwap(wpn->Recoil); fread(&wpn->Recharge,sizeof(float),1,fp); EndianSwap(wpn->Recharge); fread(&wpn->Drain,sizeof(float),1,fp); EndianSwap(wpn->Drain); fread(&wpn->ROF,sizeof(float),1,fp); EndianSwap(wpn->ROF); fread(&wpn->ProjSpeed,sizeof(int),1,fp); EndianSwap(wpn->ProjSpeed); fread(&wpn->ProjSpeedVar,sizeof(float),1,fp); EndianSwap(wpn->ProjSpeedVar); fread(&wpn->ProjSpread,sizeof(float),1,fp); EndianSwap(wpn->ProjSpread); fread(&wpn->ProjAmount,sizeof(int),1,fp); EndianSwap(wpn->ProjAmount); fread(&wpn->LaserSight, sizeof(int), 1, fp); EndianSwap(wpn->LaserSight); fread(&wpn->UseSound,sizeof(int),1,fp); EndianSwap(wpn->UseSound); if(wpn->UseSound) { wpn->SndFilename = readString(fp); // Load the sample wpn->smpSample = LoadGSSample(dir,wpn->SndFilename); if(wpn->smpSample == 0) wpn->UseSound = false; } wpn->Projectile = LoadProjectile(fp); } wpn->ROF /= 1000.0f; wpn->Recharge /= 10.0f; } // Extra stuff // Ninja Rope fread(&RopeLength,sizeof(int),1,fp); EndianSwap(RopeLength); fread(&RestLength,sizeof(int),1,fp); EndianSwap(RestLength); fread(&Strength,sizeof(float),1,fp); EndianSwap(Strength); // Worm fread(&Worm, sizeof(gs_worm_t), 1, fp); EndianSwap(Worm.AngleSpeed); EndianSwap(Worm.GroundSpeed); EndianSwap(Worm.AirSpeed); EndianSwap(Worm.Gravity); EndianSwap(Worm.JumpForce); EndianSwap(Worm.AirFriction); EndianSwap(Worm.GroundFriction); fclose(fp); // Save to cache cCache.SaveMod(dir, this); return GSE_OK; }
Tuohan on kovin yksinkertaista koodia. Alussa availlaan tiedostoa, luetaan sieltä hieman tietoa ja tarkastetaan, että on oikeanlainen tiedosto käsittelyssä. Sitten vaan luetaan tiedostosta arvoja erilaisten luokkien jäseniin. Sitten vielä jokaisella luetulla arvolla kutsutaan tuota EndianSwap funktiota.
Kerta tuon pelin koodikin on käytössä, niin ei pitäisi olla hankala homma vaikka sen pohjalta tehdä pientä ohjelmaa, joka osaa lukea ja tuottaa noita tiedostoja. Siitäpä vaikka mukava harjotustyö vehkis91:lle.
Kuitenkin, jos aikoo toisen koodia käyttää, niin tulee aina tarkistaa alkuperäisen koodin lisenssi. Kunnioitetaan niitä tekijän oikeuksia.
Tuo on freeware(?) en oikeen osaa noita c:n tiedostonkäsittely-juttuja, mutta voinhan minä kokeillakkin tehdä sellaisen de-compilerin...
Edit: typoja
Freeware ei varsinaisesti ole mikään lisenssi, vaan lähinnä nimitys ohjelmille, joita saa joidenkin (tekijänoikeuksien haltijan päättämien) ehtojen mukaisesti käyttää ilman maksua. Lisenssin sijaan freeware-ohjelmia yhdistää lähinnä se, että niiden mukana harvoin julkaistaan lähdekoodia, eikä tekijä näin ollen anna oikeuksia lähdekoodin tutkimiseen, puhumattakaan sen levittämisestä muokattuna.
Käsittääkseni Sourceforgesta löydät vain avoimen lähdekoodin ohjelmistoja, joten pienellä vaivalla löytänet myös ko. projektin tarkemmat lisenssiehdot. Tekijänoikeuksien kunnioittaminen on suhteellisen hyvä idea. :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.