Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums



(Advanced Search)

Forum Statistics
» Members: 7,024
» Latest member: Armeat2005
» Forum threads: 2,349
» Forum posts: 12,235

Full Statistics

Online Users
There are currently 242 online users.
» 0 Member(s) | 239 Guest(s)
Google, Bing, Twitter

Latest Threads
DOF2.1 (DOF2 Updated)
Forum: Libraries
Last Post: GracieStith
3 hours ago
» Replies: 1
» Views: 845
Kontak Layanan CIMB Niaga...
Forum: Support
Last Post: bosquee9053
Yesterday, 03:44 PM
» Replies: 0
» Views: 16
CS Bank DBS Customer Cent...
Forum: Chat
Last Post: bosquee9053
Yesterday, 03:37 PM
» Replies: 0
» Views: 18
Sponsors and Donations
Forum: Questions and Suggestions
Last Post: NoxxeR
Yesterday, 05:48 AM
» Replies: 0
» Views: 28
I know Kalcor left the bu...
Forum: Questions and Suggestions
Last Post: NoxxeR
Yesterday, 05:40 AM
» Replies: 2
» Views: 68
Best practices for conver...
Forum: Tech
Last Post: Mido
2025-04-19, 09:53 PM
» Replies: 1
» Views: 81
A simple suggestion as a ...
Forum: Questions and Suggestions
Last Post: Mido
2025-04-19, 09:47 PM
» Replies: 1
» Views: 39
Steps to unlock Apple ID ...
Forum: Tech
Last Post: fubolink
2025-04-17, 03:50 PM
» Replies: 0
» Views: 39
What got you into SA-MP a...
Forum: Chat
Last Post: alecnia
2025-04-17, 01:17 AM
» Replies: 1
» Views: 150
I would like to know abou...
Forum: General Discussions
Last Post: Wriney
2025-04-15, 07:14 AM
» Replies: 0
» Views: 63

 
  Free webhosting with no ads
Posted by: NoxxeR - 2023-01-19, 04:16 PM - Forum: Tech - Replies (1)

https://tinkerhost.net/

Is one of the best hosting out there for blogs, you get 5GB space and with a good cpanel,


  Y-less have patented the game sa-mp and open mp?
Posted by: NoxxeR - 2023-01-17, 12:27 PM - Forum: Chat - Replies (5)

Question for y-less, did you patent the game, some time ago people leeched the sa-mp source code and some people stole it.

If you patent the game then nobody can steal your source code just like that, then you can sue them :)

Will be lots of fun to play in the future the san andreas open multiplayer game :D


Exclamation I need help for plugins
Posted by: cr32 - 2023-01-11, 10:50 PM - Forum: Pawn Scripting - Replies (1)


  1. (plugins/mysql.so: symbol __cxa_pure_virtual, version libmysqlclient_16 not defined in file libmysqlclient_r.so.16 with link time reference)(plugins/sampac.so: cannot open shared object file: No such file or directory)(libonig.so.2: cannot open shared object file: No such file or directory)


  I did some baking.
Posted by: Y_Less - 2023-01-10, 12:09 AM - Forum: Chat - Replies (5)

[Image: 20230108_145801.jpg]
[Image: 20230108_150448.jpg]
[Image: 20230108_152601.jpg]
[Image: 20230108_165001.jpg]
[Image: 20230108_200932.jpg]
[Image: 20230108_211155.jpg]
[Image: 20230108_214619.jpg]
[Image: 20230108_220913.jpg]
[Image: 20230108_222142.jpg]
[Image: 20230109_180808.jpg]
[Image: 20230109_181424.jpg]
[Image: 20230109_184232.jpg]
[Image: 20230109_185434.jpg]
[Image: 20230109_185438.jpg]
[Image: 20230109_185441.jpg]
[Image: 20230109_190612.jpg]
[Image: 20230109_190637.jpg]
[Image: 20230109_191730.jpg]
[Image: 20230109_191736(0).jpg]
[Image: 20230109_191736.jpg]
[Image: 20230109_191746.jpg]


  We are finally open-source!
Posted by: Y_Less - 2023-01-09, 10:34 PM - Forum: Development Updates - Replies (3)

[Image: 211420467-17a8a791-62aa-459d-805d-8b87b5eb8f84.jpg]

https://github.com/openmultiplayer/open.mp

Also, server version 1.0 is out with minor fixes from RC1:

  • Server: Fix .so being required on Linux legacy plugins.
  • Server: reloadfs reuses its slot to preserve filterscript order.
  • Server: Attached objects are correctly shown to other players.
  • Server: Fix a crash when loading invalid pawn memory.
  • Pawn: Added GetPlayerMarkerForPlayer.
  • Pawn: Added a_??? file wrappers.
  • Upgrader: Supports multiple codepages.
  • Upgrader: Exclude files.
  • Upgrader: Full replacements report.

This is of course now at the updated download location of:

https://github.com/openmultiplayer/open.mp/releases

Also don't forget...

https://opencollective.com/openmultiplayer
https://www.patreon.com/open_mp


  Dayrpg V2
Posted by: Dayrpg - 2023-01-09, 12:56 PM - Forum: Hungarian/Magyar - No Replies

Day RPG
server28.clans.hu:7793

A Következő kisebb leírás engem és a szerveremet fogja bemutatni!
[spoiler=Szerver információk]-Átlag 10-15/30
-Adminok átlag: 22+
-Scripter: CMike
-Szerver web: Még nincs
-Facebook: FB.COM/SAMPDAYRPG
-IP: server28.clans.hu:7793[/spoiler]

Rólam


Sziasztok! Régóta játszom a San andreas többjátékos módjával a samp-al.
Elsőnek egy Freeroam szerveren kezdtem, majd rátaláltam egy RP szerverre pályafutásom 2. napján.
Semmit nem tudtam, mindent megamtól kellett megtanulnom az RPről.
Életem első szervere az akkori Fantasy RPG, egy alap, félig magyar nyelvű mod volt.
Akkoriban nem is volt ilyen sok RP szerver, tehát mindenki imádta aki ott játszott.

Semmit nem tudtam az RPről, mindíg rettegtem ha valaki interakcióba akart lépni velem, nehogy valamit rosszul csináljak.
Szerencére nem adtam fel és ma már a sokadik szerveremet futtatom! (több-kevesebb sikerrel)
Mára már kissé koros vagyok a játékhoz, de úgy érzem, hogy még 60 évesen is fel-fel fog lángolni bennem a SA-MP iránti elkötelezettségem.
A Játékot valamikor 2009-2010 kötöl kezdtem ha jól emlékszem az akkori 0.3a verzión. Egészen onnan jelenvagyok.
Szóval ma már sok éve játszok, kisebb kihagyásokkal.
Rengeteg Scripterrel dolgoztam együtt és több sikeres szervert is futtattunk.
A Legutolsó saját projectem 2013 környékén indult és a Second Chance GFRP nevet kapta.
A Játékmód azóta is megvan, de rajtam kívül másoknak is.
A Módban majdnem mindent sajátkezüleg írtam: Kocsi,ház, biznisz, bandák, munkák(jól kidolgozott), frakciók...egyszóval 99%-a a saját kezem műve.
A Módot bár eladtam egyszer és kikerült a publikum elé, én még máig is fejlesztem néha-néha. Jelenleg is béreltem egy szervert neki és futtatom, bár nem arra koncentralok, hanem a dayrpg-re.
Jelenleg egy másik SecondChance is indulni tervez, de ahoz semmi közöm. Nem az én módomat használják fel és remélem, hogy sikeresek lesznek.
Erről megkérek mindenkit ne is írjon hozzászólást, mert tudok róla!



Most pedig jöjjön az, amiért a témára kattintottál!

A Szerver módja egy Holiday mód.
Ezt a módot egy volt adminom adta, aki később otthagyta a szervert.
A Szerver neve valamiért a DayRPG nevet kapta, nem szóltam bele, nem foglalkoztam vele.
Mint később kiderült, az eredeti DayRpg is megnyitott pont 1-2 nappal az után, hogy én is megnyitottam!

Szóval már tisztázhatjuk is, hogy ez nem az eredeti Day mod és nem is az eredeti tulajok/adminok vezetik!
Sok rosszat olvastam az akkori Day RPG-ről, de remélem mindenki elnézi nekünk az akkori baklövéseiket, ugyanis mint írtam: Mi nem ők vagyunk!


A Módról csak annyit, hogy egy bughalmaz volt, a mai napig is találunk még bugokat, de minden nap azért dolgozom, hogy ezek eltűnjenek.
Az elején fejleszteni semmit sem tudtam, ugyanis annyi hibás rész volt, hogy rengeteg időbe telt javítani, de mostmár szerencsére egyre használhatóbb!
Szerencsére lassácskán el is tudtam kezdeni fejleszteni a modot, bár lassan haladok egyedül.
Ha feljössz a szerverre, akkor egy alap Holiday-nek fog tűnni, de az igazság a mód belsejében van.
Megtehettük volna azt is, hogy csak szét mappoljuk, hogy minél jobban nézzen ki, meg úgy tűnjön mintha jaj de sokat fejlesztettünk volna, de akkor nem lenne semmi újdonság.

Csak párat említenék, ami javítva/fejlesztve lett...
-Kamionos munka
-Fizetések
-Hosszú sorok tördelése
-Ékeztes parancsok(:D)
-Frakcióskin
-Boltrablás
-Halál utáni kórház
-Anticheat
-Egyéb szerver biztonsági dolgok
-Fegyverrel kapcsolatos hibák
-1-2 Új Map
-És még sok más!

A Szerveren található rengeteg munka, felsorolnám azokat, amiket a legtöbben használnak
-Permetező
-Hullaszállító
-Úttisztító
-Cement szállító
-Vasazás
-Pizza szálltó
-Postás

És még sok más


Jelenleg használatban lévő frakciók
-Sheriffség
-Mentőszolgálat
Alvilág
Jelenleg csak 1 banda működik a szerveren és mostanában nem lesz kiadva több!


A Szerveren GFRP szabályok szerint kell játszani. Az igazi RP-re vágyóknak ez a szerver nem ideális!
--Úgy mint ez előtt 10 évvel---


[spoiler=iratlan szabályok]
Admin felvétel NINCS, ha adminra van szükségünk, majd a vezetőség kiválasztja azt, aki a legalkalmasabbnak tűnik! Ezt kérlek hagyjátok ránk!
Frakció pályázat nincs, Leadereket is mi választunk a saját módszereink alapján!
Frakcióba jelentkezés jelenleg csak IC lehet, későbbiekben majd a weboldalon is!
Weboldal jelenleg fejlesztés alatt
[/spoiler]




[spoiler=Szerver információk]-Átlag 10-15/30
-Adminok átlag: 22+
-Scripter: CMike
-Facebook: FB.COM/SAMPDAYRPG
-IP: server28.clans.hu:7793[/spoiler]


  open.mp Server RC1
Posted by: Y_Less - 2023-01-05, 10:37 PM - Forum: Development Updates - Replies (36)

Happy New Year @everyone

It's here!

It's finally here!

After four years, two rewrites, arguments and drama, and countless other hurdles; it is finally here!

Release Candidate 1 (RC1) of the open.mp server.

This, hopefully, represents the final version of the code for our 1.0 release, and if everything goes smoothly with this version we will be able to finally openthe so-called open.mp in just a few days from now.

Before I get in to the meat of the release I want to first sincerely thank every member of the open.mp team for helping the mod get this far. It has not been easy, mostly because of how invested everyone truly was - we all wanted what was best for the mod, for the community, for SA:MP, for our servers, and for our players; we wouldn't have embarked on this journey if that wasn't the case. Unfortunately strong differing opinions on what is bestsometimes causes friction. But we're here now. So to all, a huge thank you:

  • Amir
  • Cheaterman
  • Freaksken
  • Graber
  • Hual
  • Josh
  • JustMichael
  • kseny
  • Nexius
  • pkfln
  • Potassium
  • Southclaws
  • TommyB
  • Y_Less
  • Zeex
  • And probably more...

Anyway, now the bit you actually care about...

Now we're out of beta, we're (if all goes well this week) releasing on time. So along with the server itself, which you've seen a dozen times before, we have some new goodies for you:

Pawn

The download has the official includes, no more patching the old SA:MP includes with omp.inc, now we're doing it properly! It also has a new compiler. Ever wonder when 3.10.11 was coming? Well wait no longer (if you built it yourself, you could think of this one as 3.10.12)! With this combination you'll probably get loads of new warnings, but worry not - we have a tool for that as well, to automatically upgrade a load of code, adding well-defined symbol names, const, and more in all the right places. Maybe you already noticed this, you've been using it for months, but the virtual machine (the bit inside the server) has been updated as well! Oh, and all those string natives you know and love, like SendClientMessage and AddMenuItem? They all format now. All of them*.

Documentation on the updated includes:

https://github.com/openmultiplayer/omp-stdlib

Documentation on the new compiler:

https://github.com/openmultiplayer/compiler/
https://github.com/pawn-lang/compiler/

Documentation on qawno:

https://github.com/openmultiplayer/qawno/

Documentation on the upgrader tool:

https://github.com/openmultiplayer/upgrade

A full list of what's available:
  • Symbol length limit increased to 64, no more OnPlyrDoTheTing to try and fit your names in. Leading to...
  • Multiple natives decompressed - is Col short for Colour or Collision? Now you know!
  • Tags. Tags everywhere. See the included documentation.
  • The official includes are finally const-correct. No more complaining that some people might not have them.
  • Compiler version updated: __nameof, __addressof, fixes, and too many more things to go in to here.
  • switch is way faster.
  • More warnings for previously undetected issues. The more problems the compiler can find, the fewer you need to.
  • An upgradertool to add tags and const to user-code and fix several new warnings.
  • More consistent naming. Every native has been closely examined and compared to ensure the maximum level of similarity and intuitiveness in naming.
  • Added {Float, _}:... everywhere. What does this mean? It means no more format()**- think y_va but natively.
  • -O2, the highest pawn optimisation level, works when using the new compiler and VM. Some includes may need to be updated, but some already have. To help with that...
  • The __optimisation macro was added so code can configure itself when compiled with -O2.

*Almost all of them.
**Almost no more format().

SDK

Pawn is the long-standing, and still official, way to write modes for your server. It isn't going away, but for those of you who want more control we are finally releasing the full SDK (the Software Development Kit). This is a C++ interface to the server, the same one used by all the components that make up the core open.mp code. Anything they can do you can do too (compared to plugins, which were only designed to provide functions to pawn, not write modes).

We have some documentation under way, it takes time unfortunately. But in the meantime have several example components for those of you who want to get straight stuck in. These are all templates you can build upon, and go from basically nothing to a fully working component with most common features:

https://github.com/openmultiplayer/empty-template
https://github.com/openmultiplayer/basic-template
https://github.com/openmultiplayer/pawn-template
https://github.com/openmultiplayer/full-template

Also a few terms to get you started, so you can start to understand what it is that you're reading:
  • Component - A logical individual piece of the server, like objects or pickups. Ones you don't need don't need to be loaded.
  • Extension - Code that extends another bit of code. You can write component extensions, but the most common ones are player extensions, which define some structure of data to be associated with a player in addition to all their normal data like health and weapons.
  • UID - Unique IDentifier, a number that represents your component, and your component alone. This ia always required and can be got here: http://open.mp/uid
  • Entity - A thing, usually a thing a player can interact with, and which you might have a lot of. Objects are entities, but other players are also entities, even commands in a processor could be called entities.
  • Pool - Something that holds entities. When you have a lot you need to be able to access them by name or ID in some way, this is what a pool does.
  • Interface - Components use an abstract base class as an interface. This declares which methods a component has, but doesn't contain the code for the methods. Interfaces are passed around so that components can communicate with each other, but implementations are kept private.
  • SDK - The collection of all the interfaces defined by the core server.
  • ABI - An Application Binary Interface is the way compiled code talks to other compiled code. The interfaces exported by the SDK are ABI stable, which means that using two components compiled at different times will still work together.
  • pawn-natives - The library on which all native declarations are built. Useing a wrapper called SCRIPT_API around this library: https://github.com/openmultiplayer/pawn-natives
  • Event - Something that happens externally. Things like players connecting and typing commands are events. Any component can define events and tell other components when those events happen.
  • Handler - A component that wants to know when an event happens.

Features

Beside all the new features announced for pawn, there are several new (and newly announced) features in the server:
  • Per-player gang zones, as were in YSF.
  • Per-player pickups, also as in YSF.
  • AttachPlayerObjectToPlayer.
  • Better PawnPlus support.
  • :memory:, and other special names support in SQLite.
  • SQLite open flags.
  • exclude config option to not load certain components.
  • Show config parse errors, don't just silently fail.
  • SDK major version check, just in case we ever make major server changes (hopefully we won't).

Fixes

There were a few new bugs introduced in beta 11, and a few minor ones left over from before. The ones fixed include:
  • funcidx already registered warning.
  • GDK plugins (streamer etc) missing natives.
  • Random crash on GMX.
  • GDK callbacks sometimes not called.
  • No logging when requested in SQLite component.
  • Some settings not reset on GMX.
  • NPCs were connecting when there were a lot done at once.
  • .so was still needed in Linux legacy plugin names.

Links

Firstly, of course, is the new server version:

https://github.com/openmultiplayer/server-beta/releases

Secondly, the forums are back up. Head there for all your questions:

https://forum.open.mp/

Or if you prefer:

https://vk.com/open_mp

Finally, despite it being offered a few times, we have explicitly resisted any money up to this point; because we didn't feel it was right until we had proven ourselves with a release. With this post, that time is now, so if anyone wants to help support us (all donations will go towards infrastructure and future client dev work), it would be most appreciated:

https://www.patreon.com/open_mp
https://opencollective.com/openmultiplayer

And of course everything is still in active development, so please do check all the links above regularly to see what's new that we have.


  Dunzod Entered The Building
Posted by: Dunzod - 2022-12-31, 03:27 PM - Forum: Chat - No Replies

Dunzod Entered The Building!

Hello everyone, please ditch the Discord Forums. I vote BurgerShot <3

Over and out.

Happy New Year!


  Can't run the gamemode on hosting tab!
Posted by: nerfmydrugs - 2022-10-03, 04:30 PM - Forum: Pawn Scripting - Replies (2)

Hello i can't run my gamemode on the hosting tab that i bought, i can run it on my computer at all.

Quote:[10/09/2022 21:23:31]? ? Error: Function not registered: 'socket_sendto_remote_client'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'socket_close_remote_client'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_query'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_connect'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'socket_create'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'is_socket_valid'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'socket_set_max_connections'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'socket_listen'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'socket_destroy'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_insert_id'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_store_result'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_num_rows'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_retrieve_row'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_fetch_field_row'

[10/09/2022 21:23:31]? ? Error: Function not registered: 'mysql_free_result'

[10/09/2022 21:23:31] [debug] Run time error 19: "File or function is not found"

[10/09/2022 21:23:31] [debug]? socket_sendto_remote_client

[10/09/2022 21:23:31] [debug]? socket_close_remote_client

[10/09/2022 21:23:31] [debug]? socket_create

[10/09/2022 21:23:31] [debug]? is_socket_valid

[10/09/2022 21:23:31] [debug]? socket_set_max_connections

[10/09/2022 21:23:31] [debug]? socket_listen

[10/09/2022 21:23:31] [debug]? socket_destroy

[10/09/2022 21:23:31] [debug]? mysql_insert_id

[10/09/2022 21:23:31] [debug]? mysql_store_result

[10/09/2022 21:23:31] [debug]? mysql_num_rows

[10/09/2022 21:23:31] [debug]? mysql_retrieve_row

[10/09/2022 21:23:31] [debug]? mysql_fetch_field_row

[10/09/2022 21:23:31] [debug]? mysql_free_result

[10/09/2022 21:23:31] [debug] Run time error 19: "File or function is not found"

[10/09/2022 21:23:31] [debug]? socket_sendto_remote_client

[10/09/2022 21:23:31] [debug]? socket_close_remote_client

[10/09/2022 21:23:31] [debug]? socket_create

[10/09/2022 21:23:31] [debug]? is_socket_valid

[10/09/2022 21:23:31] [debug]? socket_set_max_connections

[10/09/2022 21:23:31] [debug]? socket_listen

[10/09/2022 21:23:31] [debug]? socket_destroy

[10/09/2022 21:23:31] [debug]? mysql_insert_id

[10/09/2022 21:23:31] [debug]? mysql_store_result

[10/09/2022 21:23:31] [debug]? mysql_num_rows

[10/09/2022 21:23:31] [debug]? mysql_retrieve_row

[10/09/2022 21:23:31] [debug]? mysql_fetch_field_row

[10/09/2022 21:23:31] [debug]? mysql_free_result



and showing gamemode unknown.


  Assembly tricks
Posted by: Y_Less - 2022-09-18, 11:58 PM - Forum: Tutorials - No Replies

Over the years of writing a lot of assembly in pawn I?ve developed a few tricks for things.? These are just some of them.



Calling a function by variable.



Normally to call a function you use CALL, but that only takes a constant, not a variable.? If you want to load the target address from a variable you instead need to use SCTRL to set the target.? But CALL does some other bits as well like setting the return address, which must be done manually with SCTRL using LCTRL.? LCTRL gets the current instruction pointer, but the return address should be the instruction after the SCTRL.? With this snippet it turns out that that return address is exactly nine cells later, so the code to call a function stored in a local variable called func is:



Pawn Wrote:#emit LCTRL? ? ? 6

#emit ADD.C? ? ? 36

#emit LCTRL? ? ? 8

#emit PUSH.pri

#emit LOAD.S.pri func

#emit SCTRL? ? ? 6



Control register 8



If you?re using the JIT plugin the return address needs to be modified to a new address space.? This is what LCTRL 8 does.? It takes the AMX address in pri and converts it to a JIT address.? However if you?re not using the JIT plugin there is no register eight and pri remains the same.? So always using it is perfectly safe - either the address will be correctly updated or it won?t change at all.



Named registers.



That code is already a bit unreadable.? I said the return address is nine cells later, yet 9 doesn?t appear anywhere in the code.? Also what are 6 and 8 doing?? Fortunately const values work in #emit, so we can name some of these constants and make them more readable.? The previous snippet thus becomes:



Pawn Wrote:#emit LCTRL? ? ? __cip

#emit ADD.C? ? ? __9_cells

#emit LCTRL? ? ? __jmp

#emit PUSH.pri

#emit LOAD.S.pri ptr

#emit SCTRL? ? ? __cip



[See this file]() for the full list of constant offsets defined in YSI, there are too many to list here.? But a few highlighted ones are:


  • __frame_offset - The offset of the previous frame?s pointer in the current frame.? Actually just 0, but still named to be clear.

  • __return_offset - The offset of the return address in the current frame (the value pushed in the code above).

  • __args_offset - The offset of the number of arguments passed to the current function (in bytes) in the current frame.

  • __param0_offset - The offset of the first parameter passed to the function, for example playerid in GetPlayerName(playerid, name, size);.

  • __minus1 - Just the number -1, since - is broken in #emit.

  • __cip - The control register for the current instruction pointer (cip).

  • __2_cells - The size in bytes of two cells.? Useful when adjusting other values to make it clear that it is just two cells generally, not an offset such as __args_offset.




So for example to load the number of parameters passed to the current function use:



Pawn Wrote:#emit LOAD.S.pri __args_offset // In bytes.

#emit SHR.C.pri 2 // In cells.



Or using another YSI define:



Pawn Wrote:#emit LOAD.S.pri __args_offset // In bytes.

#emit SHR.C.pri __COMPILER_CELL_SHIFT // In cells.



Current stack address.



This code will get the current address of the stack pointer (stk):



Pawn Wrote:#emit LCTRL __stk



But it will get the value in to the pri register while sometimes you want it in the alt register instead.? You could load it and move it:



Pawn Wrote:#emit LCTRL __stk

#emit MOVE.alt



But that takes two instructions and clobbers pri.? You could swap the registers about to preserve pri:



Pawn Wrote:#emit MOVE.alt

#emit LCTRL __stk

#emit XCHG



But that takes even more instructions.? Or you could just load the value straight in to alt:



Pawn Wrote:#emit STACK 0



This adjusts the stack size by naught cells.? It doesn?t get any bigger or smaller.? At first that seems pointless, but pawn-impl.pdf says this about STACK:



Quote:ALT = STK, STK = STK value



So the instruction first saves the current value of stk in alt, then adjusts the size.? We only want the first part so we NOP the second part by making the size adjustment naught, yet still get the register being saved.



Masking with shifts.



There is no AND.C so to do:



Pawn Wrote:a = b & 0xFFFF0000;



In assembly is:



Pawn Wrote:#emit LOAD.S.pri b

#emit CONST.alt? 0xFFFF0000

#emit AND

#emit STOR.S.pri a



That?s usually fine, but what if there is some data we want to keep in alt?? It could be saved to the stack:



Pawn Wrote:#emit LOAD.S.pri b

#emit PUSH.alt

#emit CONST.alt? 0xFFFF0000

#emit AND

#emit POP.alt

#emit STOR.S.pri a



But that takes many extra instructions.? But this code is the same as:



Pawn Wrote:a = (b >>> 16) << 16;



>>> and << lose data, and there are SHR.C and SHL.C instructions:



Pawn Wrote:#emit LOAD.S.pri b

#emit SHR.C.pri? 16

#emit SHR.L.pri? 16

#emit STOR.S.pri a



This is one cell longer than the first method, but two instructions shorter than the second and doesn?t clobber alt.? However, it doesn?t work for masks like 0x00FF0000 without yet another shift, at which point it probably isn?t worth the effort compared to AND, nor at all for any mask with naughts in like 0xF0F0F0F0:



Pawn Wrote:#emit LOAD.S.pri b

#emit SHR.L.pri? 8

#emit SHR.C.pri? 24

#emit SHR.L.pri? 16

#emit STOR.S.pri a



Escaping DAT



The data segment is called dat, and is distinct from the code segment cod.? The former is where all data is stored, including the stack and heap, the latter is where all the code is stored.? But to write self-modifying code of the sort found in @emit we must write to cod instead of dat, so how is that done?? The instruction STOR.pri writes the value of the register pri to the given variable, but the VM checks that these variables are valid, i.e. that they are in some active part of global memory the stack.? But there is an oversight in the indirection instructions - SREF.pri, LREF.S.alt, etc.? These take a variable and check that this variable is within the memory segment, then use the value in that variable as a pointer to the location to write to.? However, crucially this second access is NOT checked for validity, so we can write anywhere.? The code section comes immediately before the data section so we can write there using negative addresses.? The offset of dat is found in LCTRL 1, the offset of cod is in LCTRL 0, so the two together give the relative offset of cod from dat.? For example to read the parameter of HALT at address 0 in cod:



Pawn Wrote:new ptr;



// ptr = cod - dat 4

#emit LCTRL __dat

#emit MOVE.alt

#emit LCTRL __cod

#emit SUB

#emit ADD.C __1_cell

#emit STOR.S.pri ptr



// ptr = *ptr;

#emit LREF.S.pri ptr

#emit STOR.S.pri ptr



printf("Default HALT parameter: %d", ptr);



This trick is basically the core of amx_assembly, indirection, YSI, and more.? Without it there would be no code re-writing at all of the sort needed for advanced techniques like hook and inline.



You can invert strings.



For some reason this code compiles:



Pawn Wrote:Func(const str[])

{

}



main()

{

? ? new str[] = "Hello";

? ? Func(~str);

}



This is likely an oversight in the compiler because the inversion of a string is gibberish, the code will probably just crash.? But inverting an inversion gives the original value back so this is fine:



Pawn Wrote:Func(const str[])

{

}



main()

{

? ? new str[] = "Hello";

? ? Func(~~str);

}



It might seem pointless but in assembly you end up with:



asm Wrote:ADDR.pri str

INVERT

INVERT

PUSH.pri



Still pointless, except for the fact that it is a very interesting sequence of instructions that can be scanned for.? This INVERT/INVERT pair is the core of how y_inline actually locates inline functions and their names in memory (searching through the dat segment with LREF as detailed above).



Labels reset the stack.



Pawn Wrote:Func()

{

? ? new a = 4;

label:

? ? return a;

}



Compiles as:



asm Wrote:PROC

PUSH.C 4

LCRTL 5

ADD.C -4

SCTRL 4

LOAD.S.pri -4

STACK 4

RETN



So we push something to the stack, then reset the stack.? This is exploited in the decl keyword which declares a large variable without initialising it:



Pawn Wrote:decl a[128];



Becomes:



Pawn Wrote:goto after_a;

new a[128];

after_a:



Which compiles as:



asm Wrote:JUMP after_a

STACK -512

ZERO.pri

FILL 512

after_a:

LCTRL 5

ADD.C -512

SCTRL 5



Most importantly the FILL opcode is skipped, but because labels don?t modify scope a still exists.



There is at least one bit of assembly in YSI where the LCTRL/SCTRL pair generated by a label are important to functionality (Inline_NumArgs to cancel out a PUSH.pri elsewhere in the function), but they?re extremely rare for one reason - you can only jump backwards in assembly, future labels can?t be used.



Starting a function just to end it.



Consider the following function:



Pawn Wrote:sprintf(const fmat[], {Float, _}:...)

{

? ? static target[144];

? ? format(target, sizeof (target), fmat, ???);

? ? return target;

}



There are four main ways to implement this function and forward all the parameters - 1) a macro, 2) y_va, 3) copy all the parameters as in the very common bit of assembly everyone copies, 4) the clever way.? We already have most of the parameters for format on the stack, we just need to add two more.? To call a function the number of parameters in bytes is pushed, then the function is called with CALL, which adds the return address to the stack and jumps to the address specified.? The first thing in a function is then PROC, which saves the current frame pointer to the stack and sets up a new frame.? So at the moment that format is called in this function the stack looks like:


  • ???

  • ???

  • ???

  • fmat

  • arg_count

  • return_address

  • frame_pointer




target is declared static in this example to make the stack much simpler.? So really to call format we need:


  • ???

  • ???

  • ???

  • fmat

  • sizeof (target)

  • target

  • arg_count 8




Most of that data is already there if we can just modify the rest:



Pawn Wrote:// Remove the frame pointer from the stack and use it.

#emit POP.pri

#emit SCTRL 5



// Remove the return address from the stack.

#emit POP.alt



// Remove the arg count from the stack.

#emit POP.pri



// Push the two extra parameters.

const size = sizeof (target) * cellbytes;

#emit PUSH.C size

#emit PUSH.C target



// Update and push the parameter count.

#emit ADD.C __2_cells

#emit PUSH.pri



We have now modified the stack to look how we want, put the return address in alt, and set the frame pointer back to what it used to be.? So call format:



Pawn Wrote:#emit SYSREQ.C format



After format returns we need to restore the stack to how is was without clobbering alt, which still holds the return address we need, since SYSREQ.C doesn?t touch that register:



Pawn Wrote:// Remove and reset the count again.

#emit POP.pri

#emit ADD.C __m2_cells // -8



// Remove the next cell without altering any registers (tricky).

#emit SWAP.alt

#emit POP.alt



// Put the count back on the stack.

#emit SWAP.pri



// Put the return address back.

#emit PUSH.alt



Now the part this entire section has been building to - we need to get the frame pointer back out and back on to the stack.? We used SCTRL to save it (we could have saved it to a global variable, but why waste one when the control register is right there, plus a global variable might not work if the native calls a callback), so the obvious code is:



Pawn Wrote:#emit LCTRL 5

#emit PUSH.pri

#emit LCTRL 4

#emit SCTRL 5



But there?s an instruction that does all of this in one go:



Pawn Wrote:#emit PROC



So you may sometimes see PROC randomly in the middle of a function, and this is what it is doing.? In fact it isn?t unusual to see:



Pawn Wrote:#emit PROC

#emit RETN



Which is the name of the section - we call PROC just to set up the stack correctly for calling RETN.



The stack doesn?t even need restoring.



Normally after calling a native you need to remove all the parameters pushed for it, but you don?t after calling a normal function - RETN does that for you.? In the above example we needed to restore the stack to how it was before format was called, but sometimes you don?t need to because the native is the last thing done in the function.? In that case we can just exploit RETN to remove all the extra parameters we added too:



Pawn Wrote:// As before.

#emit POP.pri

#emit SCTRL 5

#emit POP.alt

#emit POP.pri

const size = sizeof (target) * cellbytes;

#emit PUSH.C size

#emit PUSH.C target

#emit ADD.C __2_cells

#emit PUSH.pri

#emit SYSREQ.C format



// Leave the two extra parameters on the stack and just pretend they were passed to us.

// Push the return address again.

#emit PUSH.alt



// Put the frame pointer back and end the function.

#emit PROC

#emit RETN