• Ei tuloksia

Autonomisesti peliä pelaavan ohjelman suunnittelu ja toteutus

N/A
N/A
Info
Lataa
Protected

Academic year: 2022

Jaa "Autonomisesti peliä pelaavan ohjelman suunnittelu ja toteutus"

Copied!
46
0
0

Kokoteksti

(1)

KARELIA-AMMATTIKORKEAKOULU Tietojenkäsittelyn koulutus

Tomi Hietala

AUTONOMISESTI PELIÄ PELAAVAN OHJELMAN SUUNNITTELU JA TOTEUTUS

Opinnäytetyö Toukokuu 2021

(2)

OPINNÄYTETYÖ Toukokuu 2021

Tietojenkäsittelyn koulutusohjelma Tikkarinne 9

80200 JOENSUU

+358 13 260 600 (vaihde) Tekijä(t)

Tomi Hietala Nimeke

Autonomisesti peliä pelaavan ohjelman suunnittelu ja toteutus

Tiivistelmä

Tässä opinnäytetyössä suunnitellaan ja toteutetaan autonomisesti peliä pelaava oh- jelma. Ohjelma toteutettiin peliin nimeltään MapleStory. MapleStory on sivulta kuvattu 2D-tasohyppelypeli. Eettisistä syistä suunnittelu ja toteutus keskittyi pelin päivitykseen numero 83, jota pyöritetään paikallisella pelipalvelimella. Päivitys on jo yli kymmen vuotta vanha eikä se ole enää virallisesti käytössä. Ohjelman tarkoituksena on, että se liikuttaa pelihahmoa, jonka kontrolloinnista pelaaja vastaa yleensä itse. Hahmon liikutta- minen onnistuu normaalisti vain yhdessä peli-ikkunassa, sillä pelisovellus vaatii aitoja näppäimistön syötteitä hahmon liikuttamiseen. Tämän vuoksi haasteeksi otettiin myös hahmon liikuttaminen samanaikaisesti yhden tietokoneen useassa eri peli-ikkunassa.

Opinnäytetyön tuloksena syntyi ohjelma, joka osaa pelata peliä itsenäisesti. Ohjelmalle saatiin toteutettua opinnäytetyössä asetetut toiminnallisuusvaatimukset.

Kieli suomi

Sivuja 45

Asiasanat

botti, assembly, c++, takaisinmallinnus, funktion kytkentä, kutsutavan kaappaus

(3)

THESIS May 2021

Degree Programme in Business Information Tech- nology

Tikkarinne 9 80200 JOENSUU FINLAND

+ 358 13 260 600 (switchboard) Author

Tomi Hietala Title

Designing and Developing a Program to Play a Game Autonomously.

Abstract

In this thesis a program is designed and developed to play a game autonomously. The program is developed for a game called MapleStory. MapleStory is a side-scrolling 2D platform game. For ethical reasons, the design and development of the program is being focused on the update version 83 of the game and the game server is hosted as a lo- calhost. The update is over ten years old and is no longer in any official use. The aim of the program is to control a game character that is normally being controlled by the player. Controlling the character usually works in one game window at a time, since the game program requires real keyboard inputs to move the character. For this reason, one of the challenges in the thesis was to be able to control multiple game windows on the same computer simultaneously.

As a result of this thesis, a program that plays the game autonomously was successfully developed. The program managed to reach the required functionality set by the thesis.

Language Finnish

Pages 45

Keywords

bot, assembly, reverse engineering, function hook, calling convention hook

(4)

Sisältö

1 Johdanto ... 6

2 Tietoperusta ... 7

2.1 AlphaGo ... 9

2.2 MarI/O ... 10

2.3 OpenAI Five ... 10

2.4 Unity-botit äärellisellä automaatilla ... 13

3 Työkalut ... 14

3.1 Microsoft Visual Studio Enterprise 2019 ... 14

3.2 Cheat Engine ... 14

3.3 Ghidra ... 15

3.4 HaRepacker ... 16

3.5 HeavenMS ... 16

4 Ohjelman suunnittelu ja toteutus ... 16

4.1 Tietoa MapleStory-pelistä ... 17

4.2 Pelihahmon kontrollointi ... 18

4.3 Verkkopakettien kaappaaminen ... 24

4.4 Pelikartan tietojen etsiminen ... 28

4.5 Vihollisten sijaintien etsiminen ... 33

4.6 Reitinhaun toteutus ... 37

5 Tulokset ... 40

6 Pohdinta ... 42

Lähteet ... 44

(5)

Sanasto

Botti Tietokoneohjelma, joka suorittaa sille mää- rättyjä prosesseja itsenäisesti.

DLL Injektointi Tekniikka, jossa pakotetaan toinen ohjelma lataamaan DLL-tiedosto omaan muistiinsa.

DLL-tiedosto Microsoftin ”Dynamic-link library” kirjasto.

Kirjasto sisältää tietoa, jota muut ohjelmat voivat käyttää omassa koodissaan.

Takaisinmallinnus Prosessi, jossa selvitetään ohjelman toi- mintaa ilman lähdekoodia.

(6)

1 Johdanto

Tämän opinnäytetyön tavoitteena on kehittää ja toteuttaa autonomisesti peliä pelaava ohjelma peliin nimeltä MapleStory. Peli oli entuudestaan tuttu ja sen toi- minta sekä mekaniikka oli tiedossa, joten autonomisesti peliä pelaavan ohjel- man toteuttaminen oli mahdollista. Aihe valikoitui opinnäytetyöhön sen mielen- kiintoisuuden sekä haastavuuden vuoksi. Työssä käytetään työkaluja ja

tekniikoita, joita ei jokapäiväisessä ohjelmointityössä tule vastaan, kuten peliso- velluksen takaisinmallinnusta, verkkopakettien kaappaamista sekä funktion kyt- kentöjä. Nämä monet uudet tavat motivoivat opinnäytetyön tekemistä, ja opin- näytetyö tarjoaa lukijalle erilaisen lähestymistavan tehtävien automatisointiin.

Opinnäytetyössä kehitettyä ohjelmaa kutsutaan nimellä Aurora. Eettisistä syistä johtuen ohjelman kehitys ja suunnittelu sijoittuu pelin versioon 83, joka on jul- kaistu vuonna 2010 eikä ole enää virallisesti käytössä. Kehitystä tehdään pai- kallisella MapleStory-pelipalvelimella. Pelipalvelin tai pelisovellus eivät kumpi- kaan tarjoa minkäänlaista ohjelmointirajapintaa kehityksen avuksi, joten tarvittavat tiedot, kuten hahmon liikuttamisen funktiot on haettava pelisovelluk- sesta takaisinmallinnuksen avulla.

Aurora toteutetaan C++-, C- ja Assembly -ohjelmointikielillä Visual Studio -ohjel- mointiympäristössä. Oletuskielenä Auroran ohjelmoinnissa on C++-ohjelmointi- kieli. C- ja Assembly-kieliä tarvitaan pelin muistin muokkaamiseen ja oman koo- din ajamiseen pelin muistissa. Auroran lähdekoodista koostetaan DLL-tiedosto, joka injektoidaan pelisovelluksen muistiin pelin ollessa käynnissä. Tämä mahdol- listaa sen, että pelin muistia voidaan lukea täysin ongelmitta ja että ohjelma pysyy käynnissä niin kauan kuin pelisovelluskin.

Tavoitteena työssä oli saada suunniteltua ja kehitettyä C++-ohjelma, joka kont- rolloi pelihahmoa sekä suorittaa sille annettuja tehtäviä. Auroran tarkoituksena on etsiä lähin vihollinen, etsiä reitti lähimpään viholliseen A*-algoritmin avulla, kä- vellä tämän vihollisen luo, tappaa vihollinen, kerätä viholliselta tippuvat tavarat ja

(7)

toistaa prosessia, kunnes ohjelma sammutetaan. Tavoitteena on myös, että Au- rora pystyy kontrolloimaan yhtä pelisovellusta kerralla, mutta sen on myös mah- dollistettava useamman Aurora-ohjelman avaamisen samalla tietokoneella on- gelmitta.

Työssä käydään ensin läpi opinnäytetyön tietoperustaa. Seuraavaksi esitellään ja perustellaan työhön valittuja työkaluja sekä käydään läpi ohjelman suunnittelua ja toteutusta. Viimeisenä tuodaan esille opinnäytetyön tuloksia kuvailemalla oh- jelmakokonaisuuden muodostumista sekä pohditaan mahdollisia jatkokehityside- oita, jotka eivät laajuutensa vuoksi mahtuneet mukaan opinnäytetyöhön.

2 Tietoperusta

Tässä kappaleessa esitetään erilaisia tekoälytoteutuksia, joita on kehitetty pe- laamaan eri pelejä. Tähän tietoperustaan valittiin toteutuksiksi AlphaGo, MarI/O ja OpenAI Five -ohjelmat sillä nämä ovat yksiä tunnetuimpia tekoälytoteutuksia aiheesta. Kappaleessa käsitellään myös Unity-pelimoottoriin kehitettyjä botteja.

Kaikkia näistä ei ole toteutettu tietokonepeleissä, esimerkiksi AlphaGo keskittyy lautapeliin nimeltä Go. Tekoälytoteutukset näissä esimerkeissä vaihtelevat hy- vin monimutkaisista syvistä neuroverkoista ja vahvistusoppimisista yksinkertai- siin äärellisiin automaatteihin. Lähes kaikki esiteltävät tekoälytoteutukset ovat tekoälyyn erikoistuneiden yritysten ohjelmia, sillä yksityisten ihmisten toteutta- mia toteutuksia oli hyvin vähän saatavilla tai niistä ei ollut tarpeeksi tietoa tar- jolla. Esimerkiksi vain yhdestä neuroverkkoesimerkistä oli lähdekoodi saatavilla.

Toteutuksia Auroran kaltaisista ohjelmista ei kuitenkaan löytynyt muutamasta YouTube videota lukuun ottamatta, näissä videoissa ei kuitenkaan selitetty oh- jelman toimintaa tarkemmin tai ollut edes lähdekoodia saatavilla. Syynä tähän on todennäköisesti se, että vastaavanlaiset botit ovat yleensä tehty maksulli- seen tai yksityiseen käyttöön ja on haluttu suojella omaa koodia ja botin toimin-

(8)

taa. Auroran kaltaisia botteja käytetään hyvin paljolti pelin sisäisen virtuaalira- han ja tavaroiden keräämiseen, sillä näillä voi automatisoida paljon toistoa vaa- tivia tehtäviä.

Peliä pelaavista ohjelmista käytetään nimeä botti. Botit ovat tietokoneohjelmia, jotka suorittavat pelissä olevia tehtäviä ilman ihmisen apua. Botit ovat yleensä kiellettyjä moninpeleissä ja niiden käyttö aiheuttaa yleistä paheksuntaa muiden pelaajien keskuudessa. Tämän vuoksi tässä opinnäytetyössä keskitytään 10- vuotta vanhaan pelin päivitykseen, jonka pelipalvelinta pyöritän omalla koneel- lani paikallisesti. Ohjelman toteuttaminen olisi hyvin mahdollista myös nykyi- sessä päivityksessä, mutta eettisistä syistä en sellaista ohjelmaa kehitä viralli- sille pelipalvelimille.

Botit ovat hyvin yleisiä kuitenkin moninpeli peleissä, mikä on valitettavaa niiden aiheuttaman haittojen vuoksi tavalliselle pelaajalle. Suuri motivaatio bottien taustalla on virtuaalisten tavaroiden ja rahojen myyminen pelissä. Tämän vuoksi opinnäytetyössä käsitellään myös botteja, jotka ovat kehitetty joko yksinpeleihin tai ohjelmiin, joita on kehitetty moninpeleihin, mutta käytetty vain pelinkehittäjän luvalla sallitussa ympäristössä, kuten myöhemmin käsiteltävässä OpenAI Five - projektissa.

Automatisoitu pelin pelaaminen ei ole mikään uusi käsite, vastaavanlaisia ohjel- mia on kehitetty jo tietokonepelien synnystä lähtien. Mitä enemmän tekoälyalgo- ritmit kehittyvät, sitä enemmän myös botit kehittyvät. Bottiin kehitettävä tekoäly- toteutus vaihtelee botille annetun tehtävän kompleksisuudesta. Mikäli botin tulee tehdä yksinkertaisia tehtäviä, kuten kävellä annettuun pisteeseen tai hyö- kätä viholliseen, voidaan käyttää algoritmina esimerkiksi äärellistä automaattia.

Kompleksit tehtävät, kuten esimerkiksi liikkuvan kentän läpäisemiseen tarvitaan kehittyneenpää tekoälyä. Nämä kehittyneemmät tekoälyt toteutetaan neurover- koilla, joiden toteutus on haastavampaa, mutta niiden toiminta on jo aivan toi- sella tasolla.

(9)

2.1 AlphaGo

Tunnetuin tekoälyohjelma tällä hetkellä on varmastikin AlphaGo-ohjelma.

AlphaGo on DeepMind technologies -yrityksen kehittämä ohjelma, joka pelaa lautapeliä nimeltä Go. Pelissä on kaksi pelaajaa, jotka käyttävät joko valkoisia tai mustia kiviä. Pelin tarkoituksena on saartaa ja kaapata toisen pelaajan kivet laudalta ja strategisesti luoda omaa aluetta laudalle. Peli päättyy, kun mahdolli- sia siirtoja ei enää ole. Pelilaudalla olevat kivet sekä pelaamattomat kivet laske- taan yhteen, suurimman summan saanut voittaa pelin. Mahdollisia siirtoja on 10170, tämä tekee go-pelistä googol-kertaisesti vaikeampaa kuin shakista.

AlphaGo-ohjelmalle syötettiin lukuisia amatööripelejä, että se oppisi ymmärtä- mään, miten ihminen pelaa Go peliä. (DeepMind 2021.)

AlphaGo käyttää oppimiseen ja päätöksentekoon kehittyneitä hakupuita sekä syviä neuroverkkoja tekemään päätöksiä pelistä. Ohjelma käyttää useaa neuro- verkkoa päätöksentekoon, yksi verkoista on vastuussa seuraavista siirrosta, toi- nen ennustaa pelin voittajaa. AlphaGo-ohjelmalle syötettiin satoja tunteja ama- tööripelejä ja näiden amatööripelien perusteella AlphaGo ohjelmoitiin

pelaamaan itseään vastaan tuhansia kertoja. Jokaisen pelin jälkeen AlphaGo yrittää oppia virheistään ja parantaa itseään seuraavaa peliä varten. Ajan myötä AlphaGo-ohjelman päätöksenteko kehittyi niin, että se päihitti useat Gon maail- manmestarit kansainvälisillä kentillä. (DeepMind 2021.) Go–pelin 18-kertainen maailmanmestari Lee Se-Dol pelasi AlphaGo-ohjelmaa vastaan 5 ottelua, joista hän voitti yhden. Pian tappion jälkeen hän ilmoitti eläköityvänsä pelistä. Yhdeksi syyksi hän mainitsi, että vaikka hän olisi maailmanparas Gon pelaaja, on ole- massa entiteetti, jota hän ei pysty päihittämään. (Insider. 2019.)

Tekoälyn ei katsottu olevan valmista tälle haasteelle, sillä pelin uskottiin vaati- van ihmisen intuitiota. Aikaisemmat Go – peliä varten luodut ohjelmat eivät ole kyenneet voittamaan maailmanmestareita. AlphaGo – ohjelman voidaan katsoa olevan suuri saavutus ihmisen kehittämälle tekoälylle, sillä tekoälyn ei uskottu olevan valmis Go – pelin voittamiseen vielä vuosikymmeneen. (DeepMind 2020.)

(10)

2.2 MarI/O

MarI/O on YouTube-käyttäjän SethBlingin kehittämä tekoälyratkaisu Super- mario-pelin kentän pelaamiseen. Pelin tarkoituksena on päästä jokaisessa ken- tässä maaliin, joka sijaitsee kentän oikealla puolella. Maaliin pääsemistä vai- keuttaa kentässä olevat viholliset sekä haastavat hypyt tai hyppy kombinaatiot.

MarI/O käyttää koneoppimiseen neuroverkkoja sekä neuroevoluutiota eli oh- jelma oppii virheistään, MarI/O-ohjelman taustalla on Neuro Evolution of Aug- menting Topologies eli NEAT-algoritmi. Oppimisen aikana MarI/O kehittää itses- tään useita eri luokkia ja yrittää päästä kentän läpi. MarI/O – ohjelman tuottamia luokkia pisteytetään sen mukaan, miten paljon hahmo on päässyt kulkemaan oi- kealla sekä miten nopeaa se on päässyt sinne. Näistä luokista valitaan vain par- haimman pisteen saanut luokka, josta lähdetään kehittämään uutta sukupolvea.

Tätä prosessia toistetaan niin kauan, kunnes MarI/O on läpäissyt kentän.

MarI/O – ohjelman tapauksessa kentän läpäisemiseen meni noin 24 tuntia ja 24 eri sukupolvea. Neuroevoluutiota voidaan verrata oikeaan evoluutioon, sillä sen tarkoituksena on valita vain parhaimmat luokat seuraavalle evoluution tasolle.

(SethBling 2015.)

MarI/O – ohjelma ei osannut aluksi edes liikuttaa hahmoa millään tasolla, vasta usean evoluution jälkeen ohjelma kuitenkin oppi hahmon eli Marion liikuttami- sen, liikuttaminen alkoi vain siirtämällä hahmoa oikealle. MarI/O ei kuitenkaan pysty hyödyntämään oppimaansa tietoa muissa pelin kentissä, vaan sen täytyy uudestaan käydä läpi eri luokkien ja evoluutioiden vaiheet päästäkseen siihen tilanteeseen, että kentän läpäisy olisi mahdollista. Kentät eroavat toisistaan pal- jon, joten edellisessä kentässä opitun tiedon hyödyntämisestä ei ole hyötyä tässä tapauksessa. MarI/O oppi myös väistämään kentällä olevia vihollisia sekä niiden heittämiä projektiileja tehokkaasti ja tarkasti. (SethBling. 2015)

2.3 OpenAI Five

OpenAI Five on hyvin kehittynyt tekoäly ohjelma, joka on tarkoitettu pelaamaan peliä Dota 2. Dota 2 on Valve Corporationin kehittämä Multiplayer online battle

(11)

arena (MOBA)-peli, joka julkaistiin vuonna 2019 Windows-, Linux- ja OS X-alus- toille. Dota 2 on hyvin suosittu verkossa pelattava moninpeli, sillä on päivittäin miljoonia pelaajia. (Dota 2.) Pelissä pelaa kaksi viiden hengen joukkuetta toisi- aan vastaan. Pelin tarkoituksena on murtaa vastustajien puolustus ja tuhota hei- dän tukikohtansa. Pelin voittaa joukkue, joka onnistuu tuhoamaan vastustajan tukikohdan ensimmäisenä. Pelissä on 120 erilaista sankaria, joiden ominaisuu- det eroavat toisistaan. (Fandom 2021.) Yhdessä pelissä voi vain kuitenkin olla 10 erilaista sankaria samaan aikaan. Jokaisella sankarilla on omat erikoistoi- mintonsa, kuten omien tiimiläisten elämäpisteiden palauttaminen tai vahvempia hyökkäyksiä vastustajia vastaan. OpenAI Fiven tulee siis oppia nämä kaikki eri- koistoiminnot voidakseen ennustaan niitä vastaan. Pelissä pelaajien tulee ke- rätä itsellensä rahaa kartalla olevilta Creep – vihollisilta. Rahalla pelaajat voiva ostaa erilaisia tavaroita, joiden avulla pelaaja voi voittaa taistelut vihollisjoukku- een pelaajia vastaan. OpenAI Five on OpenAI yrityksen kehittämä ohjelma, oh- jelmaa on kehitetty yhteistyöllä Valve Corporationin kanssa, eikä ohjelmaa saa ladattua yksityiskäyttöön. (OpenAI 2018a)

Dota 2 on hyvin monimutkainen peli jopa ihmiselle, tekoälyn kehittäminen peliin on ollut hyvin monimutkaista. OpenAI Five on kuitenkin ollut ensimmäinen kehi- tetty tekoälyohjelma, joka pystyi voittamaan Dota 2 maailmanmestarit pelissä.

AlphaGo-ohjelman kehityksen takana ollut yritys DeepMind on myös kehittänyt omaa Dota 2 ohjelmaa, mutta se ei ole aikaisemmin pystynyt voittamaan Dota 2 maailmanmestareita. Tämä tekee OpenAI Five ohjelmasta ainoan, joka on tä- hän pystynyt. (OpenAI 2019b.) OpenAI Five käyttää viittä eri neuroverkkoa, yksi jokaiselle pelaajalle. OpenAI Five pelaa päivittäin 300 vuoden edestä pelejä it- seään vastaan, oppien jokaisesta niistä jotain uutta käyttäen OpenAI:n omaa vahvistusoppimisen algoritmiä nimeltä Proximal Policy Optimization. OpenAI Five vaatii valtavasti prosessointitehoa päästäkseen tuohon 300 vuoden päivit- täiseen pelituntiin. Ohjelmalla on käytössä 256 näytönohjainta ja 128,000 pro- sessorin ydintä. (OpenAI 2018a.)

Toisin kuin Go -pelissä OpenAI Five ei näe vastustajan hahmoja koko kentältä, sankarit kulkevat sumussa, joka rajoittaa näkyvyyttä. Oman tiimin Creep -hirviöt, rakennukset ja tiimin pelaajat antavat näkyvyyttä näiden ympärille rajatusti,

(12)

mutta muuten ohjelman on kyettävä pelaamaan sumussa rajatussa näkyvyy- dessä. OpenAI Fiven on siis pystyttävä ennustamaan vastustajien liikkumista sumussa ja tekemään päätöksiä tämän tiedon avulla. Go pelissä peli päättyy yleensä noin 150 siirron jälkeen, Dota 2 pelissä siirtoja tulee noin 20,000 yh- delle pelaajalle ja keskimääräisesti yksi Dota 2 peli kestää noin 30 minuuttia. Ai- kaa ei siis siirtojen tekemiselle jää paljoa vaan ohjelman täytyy jatkuvasti tehdä siirtoja ja ennustaa vastustajan liikkeitä. (OpenAI 2018a.)

OpenAI Five on oppinut pelaamaan täysin itsenäisesti. Vahvistusoppimiseen on käytetty vain ohjelman itsensä pelaamia pelejä. OpenAI Five näkee kentän vain numeroina, sillä ei ole graafista näkymää peliin, numerot siis esittävät pelin sen hetkistä tilannetta. (OpenAI 2019b.) Kentän näkemiseen OpenAI Five käyttää Valve Corporationin Bot API:a, täten voidaan olla varmoja siitä, että OpenAI Five näkee vain sen mitä peli sen antaa nähdä. Ensimmäisien päivien aikana OpenAI Five käveli vain ympäriinsä karttaa mikä mahdollisti sen, että ohjelma oppii tuntemaan käytettävissä olevan alustan tulevia peliä varten. Välttääkseen strategian kehityksen pysähtymistä OpenAI Five pelaa 80 % peleistä itseään vastaan, ja loput 20 % peleistä omia vanhoja sukupolvia vastaan. Tämä takaa sen, että kehitys ei pääty, vaan oppiminen pelistä jatkuu ja OpenAI Five:n stra- tegia jatkaa kehittymistään. (OpenAI 2018c.)

OpenAI Five voitti ensimmäiset pelit Dota 2:n omia botteja vastaan, mutta hävisi kun vastassa oli amatööripelaajia. OpenAI Fiven tulisi siis oppia parempia stra- tegioita voittaakseen tavallisen pelaajan pelissä. Tätä avustettiin satunnaista- malla oppimiseen käytettyjä arvoja rajummin. Hyvin pian satunnaistamisen jäl- keen OpenAI Five päihitti amatööripelaajatkin. OpenAI Five oppi pelaajien käyttämiä strategioita ilman, että niitä olisi näytetty tai opetettu manuaalisesti ohjelmalle. Neuroverkot eivät kommunikoi toistensa kanssa, vain jokainen oppii pelaamaan peliä itsestään, tämä pätee myös itse pelissä eli viisi eri neuroverk- koa tekee päätöksiä yksin. (OpenAI 2018a.) Vuonna 2019 OpenAI Five kehittyi tarpeeksi, että se pystyi voittamaan senhetkiset maailmanmestarit suorassa lä- hetyksessä Dotan maailmanmestaruus kisoissa. (OpenAI 2019b.)

(13)

2.4 Unity-botit äärellisellä automaatilla

Jason Weimannin videossa esitellään äärellinen automaatti Unity ympäristössä.

Weimann on luonut yksinkertaisin pelin, jossa hän esittelee luomiansa NPC (engl. non-player-character) botteja. Bottien tarkoitus on hyvin yksinkertainen, niiden täytyy kaataa puita ja kerätä puut maasta ja viedä talteen kartan keskellä sijaitsevaan pinoon. Kartalla myös pyörii yksi tiikeri, jota nämä NPC hahmot ti- puttavat keräämänsä puut maahan ja juoksevat karkuun, mikäli tiikeri pääsee tarpeeksi lähelle. Kaikki tämä edellä mainittu logiikka toteutetaan äärellisellä au- tomaatilla C# -kielellä Unity-kehitysympäristössä. (Weimann. 2020.)

Äärellinen automaatti on siis tilakone, joka voi olla aina vain yhdessä tilassa.

Näitä tilakoneita voidaan toteuttaa useampia kerralla toimimaan samassa koo- dissa ja ne voidaan laittaa kommunikoimaan toistensa kanssa. Tilakone toimii tila kohtaisilla tapahtumilla ja tilakoneiden välisillä siirtymillä. Jokainen tilakone määrittää, mitä tässä tilassa tehdään ja miten käyttäydytään. Tilakoneen tilana voi olla siis esimerkiksi paniikki tai puiden hakkuu. Paniikki tilassa luonnollisesti panikoidaan ja tarpeen tullen juostaan vaaralta karkuun. Hakkuu -tilassa puita hakataan, kunnes vastaanotetaan uusia tapahtumia, jotka vievät pois tästä ti- lasta. Tilakoneen vastaanottamat tapahtumat voivat olla esimerkiksi ”vie puut pi- noon” tai ”vaara ohi”. Nämä tapahtumat sitten muuttaisivat tilakoneen tilaa tai muuttavat tämänhetkisen tilan toimintaa. (Weimann 2020.)

Weimannin suunnittelema ohjelmakoodin idea voitaisiin toteuttaa myös bottina sellaiseen peliin, missä ohjattava hahmo ei ole NPC hahmo. Koodin kulku tulisi olemaan hyvin samanlainen ja samoilla tiloilla pärjättäisiin myös, ainoastaan ajettavat komennot eri äärellisen automaatin tiloissa pitäisi muuttaa eri komen- noiksi, jotka ohjaisivat hahmoa animaatioiden muuttamisen sijasta.

Voidaan siis ajatella, että botit ja NPC ovat hyvin samankaltaisia ja vaativat sa- manlaista tekoälyä. Yleisesti kuitenkin NPC-hahmojen tekoälyä ei viedä niin pit- källe kuin mitä bottien tekoälyä vietäisiin, sillä bottien toiminta tulee kuitenkin olemaan joka suhteessa monipuolisempaa ja monimutkaisempaa.

(14)

3 Työkalut

Opinnäytetyön kehitykseen on käytetty monia työkaluja. Valtaosaa työkaluista on kuitenkin käytetty vain tiedon etsimiseen pelisovelluksesta.

Työkalujen valintaan vaikutti moni asia ja jokaisen työkalun käsittelyn kohdalla käydään läpi valintaan vaikuttaneita syitä. Luvussa tuodaan mahdollisuuksien mukaan esille myös vaihtoehtoisia työkaluja ja perustellaan työhön valittujen työkalujen valintaa myös niiden kannalta.

3.1 Microsoft Visual Studio Enterprise 2019

Auroran ohjelmoinnissa käytetään Microsoft Visual Studion Enterprise -versiota.

Visual Studio on Microsoftin kehittämä ohjelmointiympäristö. Visual Studio on toiminnallisuuksiltaan hyvin rikas ja se tukee Auroran kehitykseen ja koostami- seen vaadittavia C-, C++- sekä Assembly-ohjelmointikieliä. (Microsoft 2021.)

Visual studiossa on myös mahdollista luoda C++-ohjelmalle graafinen käyttöliit- tymä ilman lisäkirjastojen asentamista. Visual C++-kirjastoja tarvittiin opinnäyte- työssä hyvin paljon, minkä vuoksi Visual Studio valikoitui ohjelmointiympäris- töksi Auroran kehitykseen. Lisäksi Visual Studio oli käytännössä ainoa

vaihtoehto kehittyneiden C++-käyttöliittymien ohjelmointiin Qt-ohjelmointiympä- ristön lisäksi. Qt on ilmainen vain, mikäli lähdekoodi on avoin. Ohjelman lähde- koodissa on koodia, jota voisi hyödyntää virallisella pelipalvelimella, joten sen käyttö ei sopinut opinnäytetyöhön eettisistä syistä.

3.2 Cheat Engine

(15)

Cheat Engine on käyttäjän ”Dark Byte” kehittämä ohjelma tietokoneen sovellus- ten muistin selaamiseen ja muokkaamiseen (Cheat Engine 2021). Cheat En- gine perustuu nykyään avoimeen lähdekoodiin ja sen lähdekoodi on vapaasti la- dattavissa GitHub palvelusta (GitHub 2021b).

Cheat Enginen avulla pelin muistista pystyttiin löytämään osa muistiosoitteista.

Muistiosoitteiden sijaintien löytämiseen käytettiin Cheat Enginen pointer scan- ner -ohjelmaa, joka etsii osoitteita annettujen tietojen perusteella. Nämä muisti- osoitteet pystyvät antamaan tietoa esimerkiksi pelin kartalla olevien köysien määrästä, niiden sijainnista tai vihollisten sijainnista.

Cheat Enginen valintaan vaikutti paljon se, että se oli työkaluna toimintatavoil- taan tuttu jo ennen opinnäytetyön kirjoittamista. Vaihtoehtoinen työkalu olisi ollut avoimeen lähdekoodiin perustuva x32dbg, mutta sovelluksen vaatiman oppimis- käyrän vuoksi päätettiin käyttää mieluummin tuttua työkalua, sillä opinnäytetyö sisälsi jo valmiiksi paljon haasteita.

3.3 Ghidra

Ghidra on tietokoneohjelmien takaisinmallinnustyökalu, joka perustuu avoimeen lähdekoodiin. Ghidran on kehittänyt Yhdysvaltain kansallinen turvallisuusvirasto NSA (engl. National Security Agency). (National Security Agency 2021.) Ghi- draa käytettiin opinnäytetyössä pelisovelluksen takaisinmallinnukseen. Hahmon liikuttamista varten pelisovelluksesta oli löydettävä funktio, joka on vastuussa näppäimistön syötteiden käsittelystä. Tämä funktio löytyi Ghidran avulla ja sen toiminta pystyttiin selvittämään Ghidran koodinselaustyökalun avulla.

Vaihtoehtoinen työkalu olisi ollut Hex Rays -yrityksen Interactive Disassembler eli IDA. Sen ilmainen versio ei tukenut pelisovelluksen takaisinmallinnukseen tarvittavia tiedostotyyppejä ja maksullinen versio olisi ollut opinnäytetyön kan- nalta suhteellisen hintava. Ghidra valittiin työkaluksi opinnäytetyöhön koska se

(16)

on ilmainen ja edistynyt työkalu tietokoneohjelmien takaisinmallinnukseen. Ko- kemusta Ghidran käytöstä ei juurikaan ollut ennen opinnäytetyön aloittamista, joten työkalun käytöstä saatiin myös uutta kokemusta.

3.4 HaRepacker

HaRepacker on Google Code -käyttäjän haha01haha01@gmail.com kehittämä ohjelma MapleStoryn pelitiedostojen tarkasteluun (Google code 2012). Työka- lun avulla on mahdollista selata karttakohtaisia tietoja sekä muuttaa näitä halu- tessa, myös pelikarttojen renderöinti on mahdollista tällä työkalulla.

Työkalu valittiin opinnäytetyöhön, koska se on ainut työkalu mitä MapleStoryn tiedostojen tarkasteluun löytyy.

3.5 HeavenMS

HeavenMS on MapleStory-peliversion 83 paikallinen pelipalvelin. Pelipalvelin on vapaasti ladattavissa GitHub-palvelussa ja sen alkuperäinen kehittäjä on Ronan C.P. Lana. (GitHub 2021a.)

HeavenMS valittiin opinnäytetyöhön koska se on edistynein saatavilla oleva MapleStoryn versio 83 pelipalvelin, sekä se on ollut aktiivisen kehityksen koh- teena useamman vuoden. Muita varteenotettavia vaihtoehtoja pelipalvelimeksi ei ollut.

4 Ohjelman suunnittelu ja toteutus

Opinnäytetyön keskeisten funktioiden ja osoittimien hakeminen aloitettiin jo lo- kakuussa 2020, sillä oli jo valmiiksi tiedossa, että funktioiden ja osoittimien löy-

(17)

täminen voi olla kovan työn takana. Kaikkia osoittimia ei heti löytynyt ja joudut- tiin turvautumaan eri ratkaisuihin, kuten pakettien kaappaamiseen, että saatiin tarvittava data Auroraa varten.

Tässä luvussa esitellään ensin lyhyesti MapleStory-peliä, tämän jälkeen käy- dään läpi pelihahmon kontrolloinnin eri vaihtoehtoja, verkkopakettien kaappaa- mista, pelikartan tietojen etsimistä ja vihollisten sijainnin etsimistä sekä lopuksi reitinhaun suunnittelua.

4.1 Tietoa MapleStory-pelistä

MapleStory on sivultapäin kuvattu massiivinen monen pelaajan verkkoroolipeli.

Pelissä ei taistella toisia pelaajia vastaan, vaan yhdessä pelaaminen on suosi- teltavaa esimerkiksi yhteistyönä tehtävien haasteiden parissa. Kuvassa 1 on MapleStoryn peli-ikkuna pelikartalla, jossa on vihollisia.

Pelin tarkoituksena on kehittää omaa pelihahmoa ja saada hahmolle mahdolli- simman korkea taso. Pelissä voi kehittää omaa hahmoansa tekemällä tehtäviä ja tuhoamalla vihollisia.

Pelissä tienataan pelin sisäistä valuuttaa tuhoamalla vihollisia ja keräämällä näiltä tippuvia tavaroita tai rahaa. Tämän vuoksi botit ovat otollisessa asemassa pelissä, sillä vihollisten tuhoamista voi niiden avulla tehdä käytännössä loputto- masti.

(18)

Kuva 1. MapleStory-pelin peli-ikkuna. (Kuva: Tomi Hietala)

4.2 Pelihahmon kontrollointi

MapleStory-pelissä pelihahmon liikuttaminen tapahtuu nuolinäppäimillä. Hah- moa voi liikuttaa vasemmalle ja oikealle, ylöspäin liikkuminen tapahtuu ainoas- taan köysien, tikkaiden ja hyppyjen avulla.

Yhtenä opinnäytetyön tavoitteena oli usean Aurora-ohjelman avaaminen yhdelle tietokoneelle siten, että ne pystyvät toimimaan yhdessä ilman ongelmia esimer- kiksi pelihahmon liikuttamisen kanssa. Tämän saavuttamiseksi täytyi tutkia useita eri vaihtoehtoja pelihahmon liikuttamiseen. Seuraavaksi esitellään kaikki kokeillut vaihtoehdot.

4.2.1 Win32 API:n PostMessageA funktio

(19)

Ensimmäisenä vaihtoehtona kokeiltiin win32 API:n ”PostMessageA”-funktiota.

Tämä funktio lähettää viestin viestijonoon käyttäen peli-ikkunan kahvaa (engl.

handle). (Microsoft 2018a.) ”PostMessageA”-funktio pystyy siis lähettämään esi- merkiksi nuolinäppäimien painalluksia viestinä peli-ikkunaan. Tämä sopisi tar- koitukseen erinomaisesti, sillä se tarkoittaisi teoriassa sitä, että useat Aurora- ohjelmat eivät haittaisi toistensa toimintaa.

Funktion testaamisen yhteydessä pelisovelluksessa ilmeni kuitenkin ongelmia.

Pelihahmo ei suostunut liikkumaan viestien seurauksena mihinkään suuntaan.

Epäilys nousi, että pelisovelluksessa on todennäköisesti tarkistus juuri tämän funktion viestejä vastaan. Ongelmia tämä funktion kanssa oli vain ja ainoastaan nuolinäppäimien kanssa, muut näppäinsyötteet toimivat niin kuin piti. Voidaan olla varmoja, että nuolinäppäimien lähettäminen onnistui peli-ikkunaan, koska pelin asetuksien säätövivut liikkuivat viestien seurauksena. Tämän funktion käyttäminen ei siis sopinut tähän tarkoitukseen.

4.2.2 Win32 API:n keybd_event funktio

Ensimmäinen pelihahmoa liikuttava funktio oli win32 API:n tarjoama

”keybd_event” -funktio. Tämä funktio simuloi aitoa näppäinsyötettä näppäimis- töstä. Funktio mahdollistaa myös näppäimen painamiseen pohjaan sekä näp- päimen vapauttamisen painalluksesta VM_KEYUP- ja VM_KEYDOWN- viesteillä. (Microsoft. 2018b.)

Tämän funktion käyttö jäi kuitenkin lyhyeen, sillä syötteitä ei voinut lähettää tiet- tyyn ikkunaan, vaan syötteet lähetettiin siihen ikkunaan, mikä sattui olemaan aktiivisena syötteiden lähetyksen aikana. Funktio ei siis ole opinnäytetyön ta- voitteiden mukainen. Pelihahmo kuitenkin liikkui nuolinäppäinsyötteiden avulla, joten tämä funktio olisi todennäköisesti valittu käyttöön, mikäli tarvetta usean peli-ikkunan samanaikaiseen kontrollointiin ei olisi ollut.

4.2.3 Pelihahmon liikuttamisesta vastaavan funktion kytkentä

(20)

Mikään valmis funktio tai kirjasto ei näyttänyt toimivan opinnäytetyön vaatimus- ten mukaisesti, joten hahmo täytyi saada liikkumaan jollakin muulla tavalla. Peli- sovelluksesta lähdettiin etsimään pelihahmon liikuttamisesta vastuussa olevaa funktiota takaisinmallinnuksen avulla.

Kuva 2. Ghidran code browser näkymä pelihahmon liikuttamisen funktiosta.

(Kuva: Tomi Hietala)

Muutaman viikon etsinnän jälkeen löydettiin ensimmäinen liikkumisesta vas- taava funktio. Muistiosoitteessa 0x9CC0A1 sijaitseva funktio vastaa hahmon lii- kuttamisesta vasemmalle ja oikealle sekä ylös ja alas köysiä ja tikkaita pitkin.

Kuvassa 2 on näkymä tähän muistiosoitteeseen sekä funktion toimintaan Ghidrassa. Kuvassa 2 näkyvät neljä CMP-määräystä tarkistavat onko mikään nuolinäppäin painettuna. Mikäli EAX-rekisterin arvo on 1 tai -1, on näppäintä painettu. Tähän funktioon kytkennän tekeminen oli yksinkertaista, sillä vain kahta arvoa tarvitsi muuttaa.

(21)

Kuva 3. Pelihahmon liikuttamiseen käytetty Assembly-koodi. (Kuva: Tomi Hie- tala)

Kuvassa 3 on hahmon liikuttamiseen käytetty Assembly-koodi. Muistiosoittee- seen 0x9CC0A1 sijoitetaan hyppy (JMP) tähän CharacterMovementHook-koo- diin. YlosTaiAlas- ja VasenTaiOikea-muuttujat ovat normaaleja kokonaisluku- muuttujia. Koodin alussa verrataan YlosTaiAlas-muuttujan arvoa nollaan. Mikäli arvo on 0, ei liikkumista tapahdu ylös tai alas ja funktio hyppää tarkistamaan onko vasen tai oikea näppäin painettuna. Arvon ollessa 1 tai -1 hahmo pyrkii kii- peämään ylös tai alas mikäli pelihahmo on köydessä tai tikkaissa. Logiikka on sama vasemmalle tai oikealle liikuttaessa. Jos VasenTaiOikea-muuttujan arvo on 1 tai -1 pelihahmo liikkuu vasemmalle tai oikealle. Koodi poistuu paluuosoit- teeseen, joka on 0x9CC0A1 + 5.

Tämä Assembly-koodi mahdollisti usean hahmon liikuttamisen samaan aikaan yhdellä tietokoneella, joka oli yksi opinnäytetyöhön asetetuista tavoitteista. Hah- mon liikuttamisen funktion kytkentä oli käytössä parin kuukauden ajan, kunnes ongelmia alkoi ilmenemään opinnäytetyön edetessä. Pelihahmo ei kyennyt esi- merkiksi hyppäämään alaspäin ylemmältä tasolta alemmalle tasolle, mikä vaatii kahden eri näppäimen painamista samaan aikaan (ALT + NUOLI ALAS). Tämä tarkoitti sitä, että funktion kytkentä olisi tehtävä uudestaan eri osoitteessa. Tämä

(22)

nykyinen muistisijainti ei simuloi oikeaa näppäimen painallusta, vaan ainoas- taan liikuttaa hahmoa. Pelisovellus tarkistaa kahden eri näppäimen painalluksen win32 API:n GetAsynKeyState-funktiolla ja tämä funktio ei tiedä nuolinäp-

päimien painamisesta tällä funktion kytkennällä.

4.2.4 Kutsutavan kaappaus

Kutsutavan kaappauksella (engl. calling convention hook) tarkoitetaan kutsuta- pojen, kuten ”__thiscall”-kutsutavan, kaappaamista pelisovelluksesta omaan oh- jelmaan, missä parametrejä voidaan muokata tai palauttaa funktion paluuarvo välittömästi. ”__thiscall” on Microsoftin kutsutapa ja se ottaa vastaan this-osoit- teen ja tämä osoite siirretään ECX-rekisterin kautta. (Microsoft. 2020.)

Kuva 4. Ghidran näkymä IsKeyPressed funktioon pelisovelluksessa. (Kuva:

Tomi Hietala)

(23)

Kuvassa 4 on IsKeyPressed-funktion pseudokoodi Ghidralla tuotettuna. Tämä funktio on vastuussa näppäimien syötteiden tarkistuksesta. Tällaisen kutsuta- van kaappaus suunnittelu ja toteutus oli hieman monimutkaisempaa, sillä aikai- sempaa kokemusta tällaisesta funktion kaappauksesta ei ollut. IsKeyPressed- funktio ottaa vastaan this-osoitteen ECX-rekisterin kautta ja kokonaisluku muut- tujan nVK parametrinä. Kuvan 4 pseudokoodissa this-osoite on myös merkitty parametriksi funktioon, mutta Microsoftin dokumentaation mukaan tämä osoite täytyy nimenomaan siirtää ECX-rekisterin kautta toimiakseen.

IsKeyPressed-funktion nVK-parametri on näppäin, minkä painamista tarkiste- taan funktiossa. Funktio palauttaa boolean-arvon, joten kaappauksen idea on yksinkertainen. Kutsutapa kaapataan Auroran avulla ja tarkistetaan nVK arvo, mikäli arvo on VK_LEFT(0x25), VK_RIGHT(0x27), VK_UP(0x26) tai

VK_DOWN(0x28), palautetaan funktio halutulla totuusarvolla takaisin pelisovel- lukseen. Pelisovellus kutsuu IsKeyPressed-funktiota jokaisen ruutupäivityksen myötä. Pelihahmoa voidaan liikuttaa esimerkiksi vasemmalle, kun palautetaan tosi (engl. true) arvo IsKeyPressed-funktion VK_LEFT-

näppäinpainallustarkistuksen myötä.

Kuva 5. GetFocus-funktion nollaus kirjoittamalla NOP (0x90) funktion kutsuun IsKeyPressed-funktiossa. (Kuva: Tomi Hietala)

Tämä kutsutavan kaappaus mahdollisti pelihahmon liikuttamisen suoraan Auro- ran kautta. IsKeyPressed-funktiossa oli kuitenkin vielä aktiivisen ikkunan tarkis- tus eikä liikuttaminen onnistunut, ellei peli-ikkuna ollut aktiivinen. Kuvassa 5 on tämän GetFocus-funktion nollaamiseen käytetty koodinpätkä. GetFocus-funk- tion kutsun muistiosoitteen kohdalle kirjoitetaan viiden tavun verran NOP (0x90) eli ei toimintaa (engl. no operation). Tämän jälkeen pelihahmon liikuttaminen

(24)

onnistui aivan ongelmitta ja alas hyppääminenkin onnistui kahden eri näp- päinyhdistelmän avulla.

4.3 Verkkopakettien kaappaaminen

MapleStory on verkossa pelattava moninpeli ja se kommunikoi pelipalvelimen kanssa verkkopakettien välityksellä. Verkkopaketit sisältävät tietoa esimerkiksi toisen pelaajan sijainnista tai saapuvista viesteistä ja niiden sisällöistä.

Verkkopakettien kaappaamisella tarkoitetaan normaalisti käyttäjältä piilossa ole- vien verkkopakettien lukemista kolmannen osapuolen ohjelmalla. Nämä verkko- paketit ovat yleensä salattuja eikä niiden lukeminen onnistu ilman salausavainta tai ovelaa kytkennän sijoitusta.

4.3.1 Verkkopakettien kaappaamisen funktion kytkennät

Pelisovelluksen verkkopaketit saatiin kaapattua sijoittamalla pelin muistiin funk- tion kytkentä, esimerkki kytkennästä on kuvassa 6. Kytkennän vuoksi kaikki pe- lisovellukseen saapuvat paketit kiertävät Auroran kautta. Kytkennät on sijoitettu siten, että salauksen kanssa ei ole ongelmia. Lähtevän paketin kytkentä on si- joitettu ennen paketin salausta, joten pakettia voidaan käsitellä siitä huolimatta, että se salataan käsitellyn jälkeen. Saapuvan paketin kytkentä on sijoitettu pa- ketin salauksen purun jälkeen, mikä tarkoittaa sitä, että paketin tietoja voidaan lukea salauksesta huolimatta. Auroralla on mahdollisuus käsitellä nämä paketit, estää pakettien saapuminen ja lähteminen sekä muokata pakettia haluttuun muotoon ennen kuin paketti päästetään pelisovelluksen omaan käsittelyyn.

(25)

Kuva 6. Saapuvien pakettien kaappaamiseen käytetty Assembly-koodi. (Kuva:

Tomi Hietala)

Pakettien saapuessa pelisovellukseen kuvassa 6 esitetty Assembly-koodi kopioi saapuvan paketin sisällön ”saapuvanPaketinStruct”-tietueeseen. Tämän jälkeen kutsutaan Auroran ”SaapuvatPaketit”-funktiota, joka vie paketin muuttujasta kä- sittelyyn tai esimerkiksi Auroran verkkopakettien muokkausohjelmaan.

Kuva 7. Auroraan kehitetty verkkopakettien muokkausohjelma pakettien visuaa- lista katselua varten. (Kuva: Tomi Hietala)

Auroran verkkopakettien muokkausohjelma antaa visuaalisen kuvan pelisovel- luksen vastaanottamista paketeista. Jokainen saapuva ja lähtevä paketti on tun-

(26)

nistettavissa toimituskoodista (engl. operation code), joka kostuu paketin kah- desta ensimmäisestä tavusta. Kuvassa 7 näkyy toimituskoodit sekä niiden sisäl- lön kuvaus. Sisällön kuvaukset löytyivät HeavenMS-pelipalvelimen tiedostoista.

4.3.2 Pakettien analysointi

Itse pakettien käsittely ja analysointi hoidetaan ilman graafista käyttöliittymää.

Pakettien analysointia varten kirjoitettiin PaketinLukija-niminen luokka. Paketin- Lukija-luokka ottaa vastaan kaksi muuttujaa: ”LPBYTE”-tyyppiä olevan paketti- jonon sekä ”size_t”-tyyppiä olevan paketin tavumäärään kertovan kokonaislu- vun. Näiden tietojen avulla pakettia voidaan lähteä analysoimaan tavu tavulta.

PaketinLukija-luokassa on myös muuttuja, joka pitää kirjaa missä tavussa ol- laan menossa paketissa tällä hetkellä. Muuttujaan summataan aina 1, 2, 4, 8 tai tekstin pituuden verran kokonaislukuja riippuen miten paljon paketista otetaan tietoa kerralla.

MapleStory-verkkopakettien tavujärjestys on little endian, eli tavujen vähiten merkitsevät tavut tallentuvat ensin. Tämä tarkoittaa, että tavut täytyy lukea myös tässä little endian -muodossa, sillä muutoin luettu data on hyvin todennä- köisesti väärin. Esimerkiksi heksadesimaali luku D4 BA on little endian -tavujär- jestyksessä 32-bittisenä luettuna 55458 ja big endian -tavujärjestyksessä 47828 (luetaan järjestyksessä BA D4).

(27)

Kuva 8. PaketinLukija luokan tärkeimmät funktiot. (Kuva: Tomi Hietala)

PaketinLukija-luokka sisältää useita funktioita pakettien lukemiseen, mutta tär- keimpinä funktioina ovat kuvassa 8 esitetyt funktiot. Näiden avulla paketista voi- daan lukea tietoa helposti ja tehokkaasti. PaketinLukija-luokka lukee paketit little endian -tavujärjestyksessä.

Kuva 9. USE_ITEM lähtevän paketin analysointi. (Kuva: Tomi Hietala)

Kuvassa 9 on esimerkkipaketti pelisovelluksesta lähtevästä paketista. Pelisovel- lus lähettää paketin, kun pelaaja käyttää jonkin tavaran pelissä, kuten esimer- kiksi juo lisävoimaa antavan taikajuoman. Kuvassa 9 on punaisella värillä mer- kittynä paketin toimituskoodi, joka on tyyppiä int16 eli kooltaan 2 tavua. Tämän lukemiseen käytettäisiin get_short-funktiota ja arvoksi tulisi kokonaislukuna 72.

Vihreällä värillä on merkitty verkkopaketin aikaleima. Aikaleima on tyyppiä int32 eli kooltaan 4 tavua ja paketista luettuna kokonaislukuna sen arvo on

10107550, lukemiseen käytetään get_int-funktiota. Sinisellä värillä paketissa on merkittynä tavaran sijainti repussa, pelaajan repussa on 96 paikkaa eri tava- roille. Tämän paketin koko on int16 ja se luetaan myös get_short-funktiolla, ko- konaislukuna arvo on 7. Viimeisenä paketissa on tavaran tunnistekoodi, tämä

(28)

tunnistekoodi kertoo mikä tavara on kyseessä. Tunnistekoodi on tyyppiä int32 ja kun se luetaan get_int-funktiolla sen arvoksi saadaan 2022179. Tunnistekoodi 2022179 vastaa pelissä tavaraa ”Onyx Apple”, eli voidaan päätellä, että pelaaja käytti tavaran onyx apple ja tavara käytettiin repun seitsemännestä paikasta.

4.4 Pelikartan tietojen etsiminen

Reitinhaku tarvitsee pelikartalta käveltävän alustan tietoja pystyäkseen tuotta- maan reitin algoritmin avulla. MapleStory-pelissä tätä käveltävää alustaa kutsu- taan jalansijaksi (engl. foothold). Jalansijojen lisäksi tarvitaan kartalla olevien köysien ja tikkaiden sijainnit.

Seuraavaksi käsitellään muutamia vaihtoehtoja näiden tietojen hankkimiseen.

4.4.1 Pelikartan lukeminen tiedostosta

Kartan tietoja lähdettiin etsimään pelin asennustiedostoissa olevasta ”Map.wz”- tiedostosta. Näitä tiedostoja pystyy lukemaan HaRepacker-ohjelmalla, joka tar- joaa myös mahdollisuuden pelikarttojen visuaaliseen tarkasteluun. Tämä

”Map.wz”-tiedosto sisälsi kaiken tarvittavan tiedon kartasta, kuten käveltävien alustojen sijainnit, köysien ja tikkaiden sijainnit sekä kartalla olevien ovien ja portaalien (engl. portal) sijainnit.

(29)

Kuva 10. Esimerkki käveltävästä alustasta ja tikkaista. Kuvassa näkyvät laatikot ovat jalansijoja ja niiden keskellä lukee jalansijan indeksi. (Kuva: Tomi Hietala)

Kuva 11. HaRepacker ikkunan näkymä kartan tiedostoja selatessa. (Kuva: Tomi Hietala)

(30)

Karttatiedot olivat hyvin yksinkertaisessa muodossa, sillä jokaiselle jalansijalle löytyi aloitus- ja lopetuspisteet ((x1, y1), (x2, y2)), jalansijan indeksi sekä edelli- sen että seuraavaan jalansijan indeksit. Köysille löytyi myös aloitus- ja lopetus- pisteet sekä indeksi. Nämä tiedot olisivat jo tarpeeksi reitinhaun toteutukseen Auroralla. Kuvassa 10 näkyy pelikartan rakenne ja kartalla olevat jalansijat. Ku- vassa 11 näkyy koko pelikartan tiedon rakenne.

”Map.wz”-tiedoston karttatiedot onnistuttiin viemään XML-tiedostomuotoon Ha- Repackerin ulosvientitoiminnolla. XML-tiedostojen lukemista varten kirjoitin XML-tiedoston jäsentäjäohjelman, joka hakee tarvittavat tiedot jokaisesta XML- tiedostosta ja tulostaa ne erilliselle tekstitiedostolle. Tämä tulostettu tekstitie- dosta tullaan sitten lataamaan ohjelman muistiin käynnistyksen yhteydessä.

Kuva 12. XML-tiedostoista koostettu tiedosto pelin kartoista. (Kuva: Tomi Hie- tala)

Karttatieto-tekstitiedosto sisältää tiedon jokaisesta pelissä olevasta kartasta ja jokaisen kartan jalansijat, köydet ja tikkaat sekä portaalit ja tiedot näiden sijain- nista ja indekseistä. Kuvassa 12 olevassa tiedostossa nähdään millaisessa muodossa tiedot ovat. Jalansijojen tiedot alkavat ”FHCount”-rivin jälkeen ja tie- dot ovat järjestyksessä x1, x2, y1, y2, next, prev. Next ja prev tiedot kuvaavat siis edellisen ja seuraavan jalansijan indeksiä ja koordinaatti pisteet kuvaavat jalansijojen sijaintia. Jalansijat ovat oikeassa järjestyksessä tiedostossa, joten

(31)

oikeat indeksit jokaiselle jalansijalle saadaan, kun iteroidaan tiedosto läpi rivi kerrallaan.

Tämä oli ensimmäinen ratkaisu karttatietojen hakemiseen. Toteutuksen jälkeen kuitenkin ilmeni muutamia ongelmia tämän ratkaisun kanssa. Jalansija-indeksit eivät enää täsmänneet, jos ”map.wz”-tiedostoon oli tehty edes pieniä graafisia muutoksia. Tämä tarkoittaisi sitä, että karttatiedot jouduttaisiin hakemaan jokai- sen muutoksen jälkeen uudestaan. Tämä on aikaa kuluttavaa ja turhaa teke- mistä, joten karttatietojen hakemiseen tarvittiin uusi ratkaisu, joka ei välitä muu- toksista tiedostoihin.

4.4.2 Pelikartan tietojen lukeminen pelin muistista

Toiseksi ja paremmaksi ratkaisuksi karttatietojen hakemiseen valittiin näiden karttatietojen lukeminen suoraan pelin muistista. Täten voidaan olla aina var- moja siitä, että Auroran lukema tieto on ajan tasalla ja jalansijojen indeksit täs- määvät. Pelin muistista voidaan lukea tietoa osoittimien avulla. Osoittimien etsi- minen pelin muistista voi olla hankalaa, mutta kun tiedetään millaista arvoa osoittimien pitäisi näyttää, on niiden etsiminen hieman helpompaa.

Ensimmäisenä tarvittiin osoite jalansijojen lukumäärään kartalla. Tämä osoite löytyi hyvinkin nopeasti, sillä HaRepacker-ohjelmalla pystyttiin tarkastamaan montako jalansijaa on tietyssä kartassa. Cheat Enginen pointer scanner -omi- naisuudella osoite löytyi parin skannauksen jälkeen. Samalla tavalla muistista löytyi myös köysien ja tikkaiden lukumäärä.

(32)

Kuva 13. Jalansijojen piirtämisessä vastuussa olevan funktion toimintaa Gridrassa. (Kuva: Tomi Hietala)

Seuraavaksi muistista tarvittiin löytää nykyisen kartan jalansijoja ylläpitävä tau- lukko. Taulukko löytyi ”MakeLayer_FootHold”-funktiosta. Funktio on vastuussa jalansijojen piirtämisestä pelisovellukseen. Siinä taulukko ladataan ECX-

rekisteriin ja pian tämän jälkeen kutsutaan GetFootholdRange-funktiota. Ku- vassa 13 on kuvakaappaus tästä funktion toiminnasta. ”MOV ECX, dword ptr [dword_00BEBFA0]” kohdassa osoitin ladataan ECX-rekisteriin. Jalansijojen osoitin syötetään funktion parametriksi kohdassa ”ZList<long>&”. Tämä yksin ei vielä riitä jalansijojen tiedon löytämiseen. Tietojen löytymiseksi osoitteeseen on lisättävä kompensaatioarvoja (engl. offset value). Näitä kompensaatioarvoja ei paljasteta tässä työssä eettisistä syistä, sillä arvojen välinen etäisyys on sama nykyisessäkin peliversiossa eikä vahinkoa haluta aiheuttaa viralliselle pelipalve- limelle. Kuvassa 14 on tulostettu Auroran lokiin jalansijat pelin muistissa.

(33)

Kuva 14. Jalansijojen tulostus pelisovelluksen muistista Aurorassa. (Kuva: Tomi Hietala)

4.5 Vihollisten sijaintien etsiminen

Vihollisten sijainnin etsimisen aloitettiin pelisovelluksen vastaanottamien paket- tien analysoinnilla. Pelisovellus on vastuussa vihollisten liikuttamisesta, mikäli pelaaja on yksin kartalla. Tämä tarkoittaa sitä, että Auroran täytyy analysoida sekä lähtevät että saapuvat paketit pitääkseen vihollislistan ajantasaisena, mi- käli kartalla on muitakin pelaajia. Lähtevien ja saapuvien pakettien analysointiin käytetään aikaisemmin mainittua PaketinLukija-luokkaa. Saapuvista verkkopa- keteista täytyy analysoida SPAWN_MONSTER(0xEC)-,

SPAWN_MONSTER_CONTROL(0xEE)-, KILL_MONSTER(0xED)- sekä MOVE_MONSTER(0xEF)-verkkopaketit ja lähtevistä paketeista jokainen MOVE_LIFE(0xBC)-verkkopaketti.

Jokaisella vihollisella pelikartalla on oma objekti-id, jolla vihollinen voidaan tun- nistaa. Tämä objekti-id ilmoitetaan ensimmäisen kerran

(34)

SPAWN_MONSTER(0xEC)- tai SPAWN_MONSTER_CONTROL(0xEE)- verkkopaketin saapuessa. Nämä verkkopaketit ilmoittavat uuden vihollisen syn- tymisestä pelikartalle. Erona näillä kahdella verkkopaketilla on se, että

SPAWN_MONSTER(0xEC)-verkkopaketti lähetetään pelaajalle vain, jos pe- laaja ei ole vastuussa tämä vihollisen liikuttamisesta. Tämä tapahtuu silloin, kun pelikartalla on myös toinen pelaaja ja viholliset jaetaan molempien pelaajien kontrolloimiksi tasaisesti. SPAWN_MONSTER_CONTROL(0xEE)-verkkopaketti lähetetään pelaajalle, kun pelaaja on yksin pelikartalla tai kun pelaaja hyökkää vihollisen kimppuun ja saa täten vihollisen oman pelisovelluksen hallintaan.

Kuva 15. SPAWN_MONSTER(0xEC)-verkkopaketin prosessointifunktio. (Kuva:

Tomi Hietala)

Kuvassa 15 on SPAWN_MONSTER(0xEC)-verkkopaketin prosessointifunktio, verkkopaketti on pidempi kuin kuvassa näkyvä prosessointi näyttää, mutta loput tavuista eivät ole tarpeellisia vihollisen sijainnin seuraamiseen.

SPAWN_MONSTER_CONTROL(0xEE) on hyvin samankaltainen verkkopa- ketti, ainoana erona on muutama ylimääräinen tavu paketin alussa, jotka ilmoit- tavat vihollisen omistajuudesta. Paketista saadut tiedot viedään muuttujaan ni- meltä viholliset, joka on tyyppiä std::map. Viholliset-muuttujassa avain-arvo- parina ovat vihollisen objekti-id ja Mob-tietue. Mob-tietue ottaa vastaan arvot vi- hollisen tunnistekoodista, sijainnista ja nykyisestä jalansijasta.

KILL_MONSTER(0xED)-verkkopaketin prosessointi on hieman helpompaa, sillä paketista ei tarvitse ottaa kuin neljä ensimmäistä tavua. Nämä tavut muodosta- vat vihollisen objekti-id:n. Tämän paketin saapuessa paketista otetaan objekti-id ja kyseinene objeckti-id poistetaan viholliset-muuttujasta.

(35)

Kuva 16. MOVE_MONSTER(0xEF)-verkkopaketin prosessointifunktio. (Kuva:

Tomi Hietala)

Kuvassa 16 on MOVE_MONSTER(0xEF)-verkkopaketin prosessointifunktio.

Funktio prosessoi vihollisten liikkumista pelikartalla. Paketista otetulla vihollisen objekti-id:llä voidaan päivittää viholliset-muuttujan listaan kyseisen vihollisen si- jainti. Tämä funktio prosessoi saapuvaa verkkopakettia vihollisen liikkumisesta, sama funktio toimisi myös pienillä muutoksilla pelisovelluksen lähettämään- MOVE_LIFE(0xBC)-verkkopakettiin.

Näiden funktioiden avulla voidaan ylläpitää listaa vihollisten sijainneista Auro- rassa. Tämä oli myös pitkään käytössä Auroran kehitystyössä. Ongelmia kui- tenkin ilmeni viholliset-muuttujan kanssa. Lista ei pysynyt ajantasaisena, mikäli hahmo liikkui isolla pelikartalla. Tämä ongelma johtui pelipalvelimen omaisuu- desta mikä on myös käytössä virallisella pelipalvelimella. Pelipalvelin ei rende- röinyt vihollisia mikäli pelihahmo liikkui liian kauas vihollisesta. Pelipalvelin lä- hetti KILL_MONSTER(0xED)-verkkopaketin, joka poisti kyseisen vihollisen käytetystä viholliset-muuttujasta. KILL_MONSTER(0xED)-verkkopaketti ei sisäl- tänyt tietoa siitä, minkä vuoksi vihollinen kuoli, joten tämä ratkaisu ei tule toimi- maan isoissa pelikartoissa.

(36)

4.5.1 Vihollisten sijainnin lukeminen pelin muistista

Vihollisten sijainnin hakemiseen päätettiin jälleen käyttää pelin muistin luke- mista. Ennen vihollisen muistiosoitteen etsimistä ei ollut varmaa pystytäänkö muistista lukemaan vihollisen sijainti, sillä pelipalvelin lähettää

KILL_MONSTER(0xED)-verkkopaketin liian kauas vihollisesta liikuttaessa.

Tämä oli kuitenkin ainut jäljellä oleva vaihtoehto vihollisten sijainnin saamiseksi.

Kuva 17. Vihollisten sijainnin osoite Ghidrassa. (Kuva: Tomi Hietala)

Vihollisten sijainnin kertova funktio toimii hyvin samankaltaisesti kuin jalansijo- jen funktio. Vihollisten sijainnin taulukko-osoite siirretään jälleen ECX-rekisteriin (”MOV ECX, dword ptr [DWORD_00BEBFA0]”), jonka jälkeen kutsutaan

CMobPool::GetMob-funktio pelisovelluksesta. Pseudokoodista paljastuu, että funktiota kutsutaan ECX-rekisterissä olevan taulukon avulla. Sijainnin löytä- miseksi tarvitaan jälleen kompensaatioarvoja osoittimeen. Nämä jätetään taas näyttämättä, sillä arvojen välinen etäisyys on sama virallisella pelipalvelimella.

(37)

Kuva 18. Vihollisten sijainnin tulostaminen pelin muistista. (Kuva: Tomi Hietala) Kuvassa 18 on vihollisten tulostaminen pelin muistista. Kaikki viholliset pelikar- talla löytyivät vihollisen sijainti osoittimesta, vaikkakin pelipalvelin pyrkii tuhoa- maan viholliset, mikäli etäisyys on liian suuri. Kuvassa 18 on myös renderöity viholliset sekä käveltävät alustat vasemmassa yläreunassa. Violetit kuviot ovat vihollisia suuressa pelikartassa. Kuvasta voi huomata, kuinka kaikki viholliset pystytään näkemään pelin muistista.

4.6 Reitinhaun toteutus

Kaikki tarvittava data reitinhakualgoritmin toteuttamiseen oli kerätty ja reitinha- kualgoritmin toteuttaminen pystyttiin aloittaa. Vaihtoehtoina reitinhakualgorit- miksi olivat Djikstran- ja A*-algoritmit. Tiedossa oli, että reitinhakuun käytettäviä solmuja (engl. node) tulisi olemaan hyvinkin paljon yhdessä pelikartassa, joissa- kin pelikartoissa voi olla jopa lähes 2000 solmua. Yksi solmu voi olla jalansija tai

(38)

köysi pelikartalla. Dijkstran- ja A*-algoritmin välinen ero haetussa reitissä on hy- vin pieni tai joissain tapauksissa eroa reitissä ei ole. A*-algoritmi voi kuitenkin heuristiikan takia olla tehokkaampi reitin etsimisessä. Dijkstran -algoritmi ei käytä heuristiikkaa, joten se voi etsiä reittiä huomattavasti useammasta sol- musta kuin A*, vaikka molemmat löytäisivätkin täsmälleen saman reitin. (Stan- ford. 2021.) On tärkeää, että reitinhaku toimii nopeasti ja tehokkaasti ja tämän vuoksi reitinhakualgoritmiksi opinnäytetyöhön valikoitu A*-algoritmi heuristiikan takia.

A*-algoritmia ei lähdetty kehittämään alusta asti itse, esimerkkinä käytettiin Git- Hubista löydettyä A*-algoritmia käyttäjältä OneLoneCoder.

(https://github.com/OneLoneCoder/videos/blob/master/OneLoneCoder_PathFin ding_AStar.cpp). Algoritmi valittiin selkeän koodin vuoksi sekä hyvän koodin kommentoinnin perusteella, sillä tämä auttoi paljon algoritmin muokkaamisessa opinnäytetyön tarkoitukseen. Algoritmi ei ole suoraan toteutettavissa Auroraan, vaan se vaatii hieman muokkauksia esimerkiksi naapurisolmujen etsimiseen.

Kuva 19. Reitinhaussa käytetyn solmun rakenne. (Kuva: Tomi Hietala)

Jalansijat, köydet ja tikkaat toimivat solmuina reitinhakualgoritmissa. Jokaisen solmun tiedot haetaan pelin muistista aina kun kartta vaihtuu. Jalansijoilla ja köysillä saattaa olla sama indeksi muistista haettuna, joten jokaiseen köyden ja tikkaan indeksiin lisätään 10000. Täten reittiä tulostaessa nähdään helposti, mi- käli algoritmi haluaa käyttää köysiä. Solmun rakenne on nähtävissä kuvassa 19.

Jokainen solmu on rakenteeltaan samanlainen.

(39)

Jalansija-solmuiIle lähdetään etsimään naapureita ensimmäisenä next- ja prev- muuttujien avulla. Nämä arvot liitetään suoraan naapuriarvoiksi. Indeksit, jotka ovat next- ja prev-muuttujissa eivät voi olla seiniä tai alustaa, jossa ei voi kä- vellä. Next- ja prev-muuttujien indeksin arvo voi olla myös nolla. Mikäli indeksi on nolla, jalansijalla ei ole naapuria tässä suunnassa. Jos molemmissa muuttu- jissa indeksit ovat suurempia kuin nolla, etsitään naapureita vain ylä- ja ala- suunnassa, sillä sivujen naapurit löytyvät jo. Jos toisen tai molempien indeksien arvot ovat nolla, etsitään naapureita joka suunnasta.

Köysillä ja tikkailla ei ole next- ja prev-arvoja, joten niiden indeksit ovat sol- muissa nolla. Näille lähdetään etsimään naapureita käymällä läpi koko kahden pisteen välinen matka 5 pisteen välein (y1 arvoon lisätään +5 kunnes y1 on yhtä suuri tai suurempi kuin y2) ja lasketaan, voidaanko hypätä toiseen köyteen tai toiselle tasolle.

Reitinhaku toimii syöttämällä algoritmille aloitussolmu ja päätössolmu, nämä solmut voivat olla joko jalansijoja, köysiä tai tikkaita. Algoritmin toimintaa ei muutettu, sillä sama algoritmi toimii lähes kaikissa tila-avaruuksissa. Algoritmin toimintaan voi tutustua paremmin yllä mainitusta linkistä. Heuristiikka tässä al- goritmissa toimii laskemalla kahden pisteen etäisyys Pythagoraan lauseella ja lyhyin reitti päätellään tämän avulla.

(40)

Kuva 20. Reitinhaun tulostus Aurorassa. (Kuva: Tomi Hietala)

Kuvassa 20 on tulostettuna reitti Auroran lokiin. Reitin aloituspiste on merkittynä Auroran vasemmassa yläreunassa olevaan renderöintiin punaisella värillä ja maali on merkattuna sinisellä värillä. Löydetty reitti käyttää kolmea eri köyttä kartalla. Maaliin pääsisi käyttämällä vain yhtä köyttä, mutta algoritmi etsi lyhyim- män reitin käyttämällä jokaisessa tasossa olevaa köyttä. Köyden kiipeäminen on yhtä nopeaa kuin käveleminen, joten reitinhaun ehdottama reitti todellakin on tässä tapauksessa nopein ja paras.

5 Tulokset

Opinnäytetyön tuloksena syntyi ohjelma, joka kykenee kävelemään pelikartalla itsenäisesti, hyökkäämään vihollisen kimppuun ja toistamaan tätä, kunnes oh- jelma sammutetaan. Tämä toteutui yhdistämällä opinnäytetyön suunnitteluvai- heessa esitetyt tekniikat.

(41)

Vihollisen sijainnin osoittimet eivät kykene näyttämään vihollisen tämänhetkistä jalansijaa, joten tämä tieto täytyy hakea itse vertaamalla vihollisen nykyistä si- jaintia kaikkiin jalansijoihin ja valitsemalla niistä lähin jalansija. Pelihahmon ja- lansijalle löytyi osoitin, joten pelihahmon jalansija on lähes aina tiedossa. Poik- keuksena tässä on, mikäli hahmo on ilmassa tai köydessä, sillä tuolloin

jalansijaa ei voida hakea, koska pelihahmo ei ole jalansijan päällä. Pelihahmon ollessa köydessä köyden indeksi on haettava vertaamalla hahmon sijaintia kaik- kiin pelikartalla oleviin köysiin ja etsimällä niistä lähin köysi. Myös hahmon ol- lessa ilmassa etsitään hahmolle lähin köysi tai jalansija etäisyyden perusteella.

Aurora etsii lähimmän vihollisen niin sanotusti linnuntietä. Aurora vertaa pelaa- jan tämänhetkistä sijaintia kaikkiin pelikartalla oleviin vihollisiin ja valitsee näistä lähimmän. Pelihahmo laitettiin seuraamaan reitinhaun tuottamaa reittiä. Uutta reittiä haetaan jatkuvasti pelihahmon liikkuessa kartalla, joten reitti maaliin on aina ajan tasalla pelihahmon tai vihollisen liikkeistä huolimatta. Pelihahmon lii- kuttamisessa tuli ottaa huomioon monet eri tilanteet, kuten esimerkiksi hyppy köyteen, hyppy köydestä toiseen köyteen, hyppy alapuolella olevalle tasolle sekä hyppy samalla tasolla olevalle tasolle, mutta joiden välissä on hypyn vaa- tiva väli. Jokaisen tapauksen huomioon ottaminen oli työlästä eikä jokaista maastoa vielä tässä vaiheessa työtä tueta. Pelihahmon liikuttaminen onnistuu kuitenkin lähes jokaisessa maastossa.

Pelihahmon hyökkäysiskujen tekeminen tehdään aikaisemmin mainitulla Post- MessageA-funktiolla. Tämä funktio toimii hyvin kaikkeen muuhun käyttöön kuin hahmon liikuttamiseen ja funktio sallii syötteen lähettämisen tiettyyn ikkunaan.

Pelihahmo hyökkää viholliseen, kun ollaan tarpeeksi lähellä vihollista. Ennen hyökkäystä on kuitenkin tarkistettava, että pelihahmo on kääntyneenä viholli- seen päin. Tämä voidaan tarkistaa vertaamalla pelihahmon animaatiota, sijain- tia ja vihollisen sijaintia. Pelihahmon animaatio kertoo, kumpaan suuntaan peli- hahmo katsoo sillä hetkellä, joten jos animaatio-osoitin osoittaa vasemmalle, kun vihollinen on oikealla, lähetetään syöte VK_RIGHT pelihahmon liikuttami- sesta vastaavalle funktiolle. Lähetetty syöte kääntää pelihahmon katseen oike- aan suuntaan hyökkäämistä varten.

(42)

6 Pohdinta

Opinnäytetyön tavoitteet olivat peliä pelaavan ohjelman luominen ja ohjelman pyörittäminen samanaikaisesti useassa eri peli-ikkunassa. Tavoitteet saavutet- tiin ja kehitettyyn työhön ollaan tyytyväisiä. Kehityskohteita Auroraan jäi kuiten- kin paljon, ja näitä tullaan kehittämään ja parantamaan myös opinnäytetyön jäl- keen. Suurimpia haasteita opinnäytetyön kehityksessä oli funktioiden ja

osoittimien etsiminen pelisovelluksesta. Näiden etsimiseen kului huomattavasti suurin osa opinnäytetyön kehitykseen käytetystä ajasta, sillä niiden sijaintia ei meinannut löytyä. Funktioiden etsimiseen täytyi opetella paljon uusia asioita ta- kaisinmallinnuksesta sekä Assembly-kielestä. Asiaa vaikeutti myös se, että ta- kaisinmallinnuksesta ei ollut paljon aikaisempaa kokemusta.

Pelihahmon ohjaamiseen käytetty kutsutavan kaappaaminen oli opinnäytetyön suurimpia onnistumisia. Tämä kutsutavan kaappaus mahdollisti usean Aurora- ohjelman avaamisen samanaikaisesti samalla tietokoneella ilman ongelmia peli- hahmojen kontrolloinnissa. Mikään valmis ratkaisu ei olisi ollut toiminnallisuuk- siltaan yhtä laaja ja tehokas. Verkkopakettien analysointiin käytetty PaketinLu- kija-luokan tekeminen onnistui myös hyvin. Luokka ohjelmointiin niin, että sitä voidaan käyttää myös tulevaisuudessa muissa projekteissa, jotka vaativat verk- kopakettien analysoimista.

Auroran toiminnallisuus on tällä hetkellä hyvin rajattua pelin kokonaisvaltaisen pelaamisen kannalta, sillä pelaajalle ominaista käyttäytymistä puuttuu, kuten esimerkiksi muiden pelaajien vältteleminen pelikartalla. Aurorasta halutaan luoda täysin automaattinen peliä pelaava ohjelma pelin käynnistyksestä lähtien.

Tämä tarkoittaisi käytännössä sitä, että olisi luotava uusi hallintaohjelma, joka käynnistää MapleStory-pelin ja injektoi Auroran tähän käynnistetyn prosessin muistiin.

(43)

Tämänhetkisiä suurimpia Auroran kehityskohteita ovat reitinhaku pelikartasta toiseen, tavaroiden myyminen lähimmälle niitä ostavalle NPC-hahmolle, peli- hahmojen eri hyökkäysvaihtoehtojen tukeminen, automaattinen sisäänkirjautu- minen peliin sekä automaattinen pelin uudelleenkäynnistys. Näiden ohjelmoimi- nen Auroraan tulee viemään paljon aikaa niiden vaativan takaisinmallinnuksen vuoksi, eikä näitä siksi voitu ottaa mukaan tähän opinnäytetyöhön.

(44)

Lähteet

Cheat Engine. 2021. About Cheat Engine

https://www.cheatengine.org/aboutce.php. 30.05.2021 DeepMind. 2021. AlphaGo - The story so far

https://deepmind.com/research/case-studies/alphago-the-story-so- far. 05.04.2021

Dota 2. 2021. Dota 2 Kotisivu

https://www.dota2.com/home. 06.04.2021

DeepMind. 2020. AlphaGo – The Movie | Full Documentary. YouTube-video.

https://www.youtube.com/watch?v=WXuK6gekU1Y. 13.03.2020 Fandom. 2021. Haettu 06.04.2021. Dota 2 Heroes

https://dota.fandom.com/wiki/DOTA_2_Heroes

GitHub. 2021b. Cheat Engine. A development environment focused on mod- ding.

https://github.com/cheat-engine/cheat-engine. 30.05.2021

GitHub. 2021a. ronancpl/HeavenMS: An improved server based on MapleSola- xia (v83 MapleStory Private Server)

https://github.com/ronancpl/HeavenMS. 28.04.2021 Google Code. 2012. hasuite.

https://code.google.com/archive/p/hasuite/. 30.05.2021

Insider. 2019. A former world champion of the game Go says he's retiring be- cause AI is so strong: 'Even if I become the No. 1, there is an entity that cannot be defeated'

https://www.businessinsider.com/deep-mind-alphago-ai-lee-sedol- south-korea-go-2019-11?r=US&IR=T 27.11.2019

Jason Weimann. 2020. Unity Bots with State Machines - Extensible State Machine / FSM. YouTube-video.

https://www.youtube.com/watch?v=V75hgcsCGOM 26.04.2020 Microsoft. 2018a. PostMessageA function (winuser.h)

https://docs.microsoft.com/fi-fi/windows/win32/api/winuser/nf- winuser-postmessagea. 28.04.2021

Microsoft. 2018b. keybd_event function (winuser.h)

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf- winuser-keybd_event. 29.04.2021

(45)

Microsoft. 2020. __thiscall

https://docs.microsoft.com/en-us/cpp/cpp/thiscall?view=msvc-160.

30.05.2021

Microsoft. 2021. Visual Studio 2019 IDE – Programming Software for Windows.

https://visualstudio.microsoft.com/vs. 28.04.2021 National Security Agency. 2021. Ghidra.

https://www.nsa.gov/resources/everyone/ghidra/. 28.04.2021 OpenAI. 2018a. OpenAI Five

https://openai.com/blog/openai-five/ 25.06.2018 OpenAI. 2019b. OpenAI Five Defeats Dota 2 World Champions

https://openai.com/blog/openai-five-defeats-dota-2-world-champi- ons/ 15.04.2019

SethBling. 2015. MarI/O – Machine Learning for Video Games. YouTube-video.

https://www.youtube.com/watch?v=qv6UVOQ0F44 13.06.2015 Stanford. 2020. Amit’s A* Pages.

http://theory.stanford.edu/~amitp/GameProgramming/AStarCompa- rison.html 23.02.2021

(46)

Viittaukset

LIITTYVÄT TIEDOSTOT

Tilastokeskuksen Digipelaaminen 2017 -tutkimuksen mukaan digitaalisten pelien pelaaminen on Suomessa nelinkertaistunut 25 vuodessa, eli 1990-lu- vun alusta.. Asiaa on tutkittu

musten  ja  käyttäjätarinoiden  tuottaminen,  (3)  käytettävyysarvioinnin  suunnittelu  tuotevertailun  tarpeisiin,  (4)  käytettävyysarvioinnin  toteutus 

Puolustavaa pelaaja tulee opettaa myös lukemaan ja ennakoimaan peliä niin, että hän pystyy mahdollisimman usein katkaisemaan vastustajan syötön.. Pallollista

Jos lainansaaja on käyttänyt korkotukilai- naa muuhun kuin tämän lain mukaiseen tar- koitukseen taikka on korkotukilainaksi hy- väksymistä hakiessaan antanut olennaisesti

Kuvio 2. Ryhmävalmennuksen sisällöt ja toteutus... Työelämätaidot olivat mukana ryhmävalmennuksessa. Valmennettavat tekivät esi- merkiksi omat sähköiset CV:t ja

Wittgensteinin vaatimus viittaisi siis siihen, että pelin logiikka on yksinkertaisesti peli itse, mikä on implisiittinen (sisäisesti kiedottu) tilanne par excellence.. Jos peli

Salon mukaan on todennäköistä, että järjestelmä on nyt tilassa, jossa jotkut pelaavan reilua peliä ja jotkut vetävät kotiin päin.. Järjestelmä olisi kuitenkin

Peli opetti minulle 1930-luvun Suomen poliittisesta tilanteesta Pidin peliä hyvänä oppimiskokemuksena. Pystyin eläytymään ryhmäni tilanteeseen