Jump to content

DuFF

Přispěvatel
  • Příspěvků

    207
  • Registrován

  • Aktivní

  • Vítězných dnů

    43

Příspěvky posted by DuFF

  1. před 11hodinami, mxco said:

    No jo, ale to že si refaktorizuje kód (a změní pořadí ifů) mu neodpoví na otázku, proč mu padá server. Takže to s tím sscanf je jen jakési doporučení.

    Při těchto obtížích je potřeba prostě klasicky debugovat (odkomentovat části kódu, vložit printy do různých bloků vypisovat si hodnoty proměnných)

    Momentálne tam má viditeľný array index out of bounds na riadkoch:

    format(string, 256, "%s %s dal hráčovi %s VIP %s na %d dní !", GetAdminRank(playerid),PlayerName(playerid),PlayerName(id),viptarif,strval(params[days]));
    DOF2_SetInt(UserPath(id),"VIP_Days", strval(params[days]));
    

    (napríklad ak zadám príkaz /setvip 0 3 99, strval(params[99]) určite nespraví nič dobré)

    Ak by sa držal doporučenia pracovať iba so sscanf, tento problém by odstránil a vedeli by sme, či pády spôsobovalo toto, alebo niečo iné.

    • Děkuji (+1) 1
    • Líbí se mi to! (+1) 1
  2. Prečo kombinuješ chrfind a strval so sscanf? Keď parametre načítaš pomocou sscanf, žiadne chrfind a strval nemusíš ďalej riešiť a môžeš pracovať priamo s premennými, do ktorých ti sscanf uložil nájdené hodnoty parametrov.

  3. Tvoja statická metóda Visit má parameter typu Visitor. Ak na objekte uloženom v premennej typu Visitor zavoláš metódu, zavolá sa metóda z triedy Visitor (ak táto metóda nie je virtual a skutočný typ objektu túto metódu pomocou override nepreťažuje).

    Metódy sa mi volali správne, keď som ich volal na objektoch uložených v premenných správneho typu (FirstVisitor, SecondVisitor, ... nie Visitor) a v tomto prípade nebolo potrebné používať virtual / override.

    Spoiler
    
    public static void Main()
    {
        Console.WriteLine("===== Visitor =====");
        var visitor = new Visitor();
        visitor.Visit(new List<Animal>());
        visitor.Visit(new List<Cat>());
    
        Console.WriteLine("===== First Visitor =====");
        var firstVisitor = new FirstVisitor();
        firstVisitor.Visit(new List<Animal>());
        firstVisitor.Visit(new List<Cat>());
    
        Console.WriteLine("===== Second Visitor =====");
        var secondVisitor = new SecondVisitor();
        secondVisitor.Visit(new List<Animal>());
        secondVisitor.Visit(new List<Cat>());
    
        Console.WriteLine("===== Third Visitor =====");
        var thirdVisitor = new ThirdVisitor();
        thirdVisitor.Visit(new List<Animal>());
        thirdVisitor.Visit(new List<Cat>());
    }

     

     

    Prípadne sa mi to ešte podarilo pridaním negenerických virtuálnych metód do Visitora, ktoré potom v derived triedach overridujem:

    Spoiler
    
    using System;
    using System.Collections.Generic;
    
    public class Program
    {
    	static void Visit(Visitor visitor)
    	{
    		var cats = new List<Cat>();
    		var animals = new List<Animal>();
    		var dogs = new List<Dog>();
    
    		Console.WriteLine(visitor.GetType().Name);
    		visitor.Visit(cats);
    		visitor.Visit(animals);
    		visitor.Visit(dogs);
    	}
    
    	public static void Main()
    	{
    		Visit(new Visitor());
    		Visit(new FirstVisitor());
    		Visit(new SecondVisitor());
    		Visit(new ThirdVisitor());
    	}
    
    	public class Visitor
    	{
    		public virtual void Visit(List<Cat> cats)
    		{
    			Console.WriteLine("Visitor - Cats");
    		}
    
    		public virtual void Visit(List<Animal> animals)
    		{
    			Console.WriteLine("Visitor - Animals");
    		}
    
    		public virtual void Visit<T>(List<T> objects) where T : Animal
    		{
    			Console.WriteLine("Visitor - Generic");
    		}
    	}
    
    	public class FirstVisitor : Visitor
    	{
    		public override void Visit(List<Cat> cats)
    		{
    			Console.WriteLine("FirstVisitor - Cats");
    		}
    
    		public override void Visit(List<Animal> animals)
    		{
    			Console.WriteLine("FirstVisitor - Animals");
    		}
    
    		public override void Visit<T>(List<T> objs)
    		{
    			Console.WriteLine("FirstVisitor - Generic");
    		}
    	}
    
    	public class SecondVisitor : Visitor
    	{
    		public override void Visit(List<Cat> cats)
    		{
    			Console.WriteLine("SecondVisitor - Cats");
    		}
    
    		public override void Visit(List<Animal> animals)
    		{
    			Console.WriteLine("SecondVisitor - Animals");
    		}
    
    		public override void Visit<T>(List<T> objs)
    		{
    			Console.WriteLine("SecondVisitor - Generic");
    		}
    	}
    
    	public class ThirdVisitor : Visitor
    	{
    		public override void Visit(List<Cat> cats)
    		{
    			Console.WriteLine("ThirdVisitor - Cats");
    		}
    
    		public override void Visit(List<Animal> animals)
    		{
    			Console.WriteLine("ThirdVisitor - Animals");
    		}
    
    		public override void Visit<T>(List<T> objs)
    		{
    			Console.WriteLine("ThirdVisitor - Generic");
    		}
    	}
    
    	public class Animal
    	{
    
    	}
    
    	public class Cat : Animal
    	{
    
    	}
    
    	public class Dog : Animal
    	{ 
    	
    	}
    }

     

    Výstup je potom:

    Spoiler
    
    Visitor
    Visitor - Cats
    Visitor - Animals
    Visitor - Generic
    FirstVisitor
    FirstVisitor - Cats
    FirstVisitor - Animals
    FirstVisitor - Generic
    SecondVisitor
    SecondVisitor - Cats
    SecondVisitor - Animals
    SecondVisitor - Generic
    ThirdVisitor
    ThirdVisitor - Cats
    ThirdVisitor - Animals
    ThirdVisitor - Generic

     

     

  4. před 1 hodinou, Hip said:

    Obávám se, že toto není možné. Bohužel budeš muset vždy, co vím, jít přes smrt hráče. Můžeš ovšem nastavit skin na jakýkoliv v průběhu hry příkazem SetPlayerSkin nebo SetPlayerSpawnPoint a pak SpawnPlayer pro spawnutí někde. Pokud ti jde vyloženě o classu, tak můžeš ve hře kdekoliv nastavit SetPlayerClass. Záleží na use case jak to chceš použít

    Možno to bude možné pomocou ForceClassSelection,

  5. Nazdar,

    práve pozerám históriu jazyka Pawn na CompuPhase a vidím tam, že vo verzii 4.0.4548 bola zmenená syntax pre inicializáciu polí a namiesto zložených zátvoriek sa začali používať hranaté.

    Máš nejaký dôvod, prečo chceš používať práve túto najnovšiu verziu jazyka pre SAMP?

    SAMP komunita momentálne väčšinou používa kompiler od Zeexa, v ktorom je opravených pár známych chýb kompilera, ktorý je priložený k SAMP serveru.

     

  6. Vďaka, doteraz som sa s y_vehicledata nestretol a ušetrí to kopec práce. 

     

    Menší detail:

    před 28minutami, Scydo said:

    if (Vehicle_IsCar(GetPlayerVehicleID(playerid) && !Vehicle_IsPolice(GetPlayerVehicleID(playerid))) return SendClientMessage(playerid, X11_RED, "Nejsi v policejním vozidle");

    Myslím, že takto by som mohol zastaviť hráča z akéhokoľvek (aj nepolicajného) vozidla, pre ktoré Vehicle_IsCar vráti false.

    • Líbí se mi to! (+1) 1
  7. Nevidel som, ako to na tých serveroch presne funguje, ale očakával by som, že na objekt biliardového stola je vložených niekoľko malých objektov biliardových gulí a že sa využíva ColAndreas plugin na zistenie, či guľa narazí do inej gule/hrany stola. Guliam vieš potom asi nastaviť rýchlosť a smer podľa rýchlosti a smeru gule, ktorá do nich narazila. U odrazov od hrán stola platí asi niečo na spôsob uhol dopadu = uhol odrazu.

    • Paráda! (+1) 1
    • Líbí se mi to! (+1) 1
  8. Tento kód:

    Spoiler
    
    #include <iostream>
    
    void CreateAccount()
    {
        std::cout << "create account" << std::endl;
    }
    
    void Login()
    {
        std::cout << "login" << std::endl;
    }
    
    int main()
    {
        bool close = false;
        while (!close)
        {
            system("CLS");
    
            std::cout << "input:" << std::endl;
            
            int option;
            std::cin >> option;
    
            switch (option)
            {
                case 0: CreateAccount();
                    break;
                case 1: Login();
                    break;
            }
    
            system("pause");
        }
    }

     

    u mňa vyzeral funkčne.
    Vymaže sa obrazovka, počká sa na input, vykoná sa vybraná úloha, počká sa na stlačenie ľubovoľnej klávesy a potom sa to celé opakuje.

  9. Stále mi nie je jasné, ako určuješ, či hráčove dáta uložiť do tabuľky first, second, alebo third.
    Ak máš nejakú funkciu, ktorá to rozhoduje (a nie je to random), možno by si ju mohol použiť znova na výber tabuľky, z ktorej budeš dáta čítať.
    Tým pádom by si nemusel robiť select zo všetkých tabuliek, ale iba z jednej.

    Btw kde ti vypísalo, že to tvoja verzia mariaDB nepodporuje? Mohol by si sem skopírovať celú tú hlášku?

  10. Si si istý, že to urobí tvoj systém prehľadnejší a nie naopak? 

    Podľa čoho sa rozhoduješ, či vložiť hráčove dáta do tabuľky first, second, alebo third? 

    Ak to naozaj chceš takto, skús v tom selecte využiť UNION, prípadne UNION ALL na spojenie riadkov z jednotlivých selectov do jedného resultu.

  11. Myslím si, že problém môže byť tam, že si síce prepísal názov príkazu, ale neprepísal si jeho dĺžku. 
    Napr. dcmd(account,7, cmdtext) si mal prepísať na dcmd(info,4, cmdtext).

    Edit: Otestoval som to a moja predošlá odpoveď je blbá.

    Skúšal si na serveri aj starý, aj nový príkaz? Nefungoval ani jeden z nich?

  12. Môžeš využiť sscanf plugin podobne, ako keď parsuješ parametre v príkazoch. Akurát namiesto params budeš parsovať inputtext.

    Výhoda oproti strval je tá, že keď strval vráti 0, tak nevieš, či si používateľ želal zadať 0, alebo zadal nejaký text, ktorý sa nepodarilo sparsovať.

  13. Myslím si, že problém je v medzere na riadku CMD: setskin.
    Ak to napíšeš takto s medzerou, nevyhodnotí sa makro na vytvorenie príkazu.
    Riešenie je teda použiť CMD:setskin (bez medzery). 

    Potom ešte neviem, čo chcel autor povedať týmto:

    před 4 hodinami, NuMeRe said:

    SetPlayerSkin (playerid, skin, 312)

    Každopádne SetPlayerSkin očakáva 2 argumenty (id hráča, ktorému má zmeniť skin a id skinu).
    Preto SetPlayerSkin(playerid, skin).

  14. Chápem to správne, že chceš, aby sa zobrazil hráčovi dialog s miestami na portnutie, keď klikne na tlačítko spawn?

    Ak áno, v OnPlayerRequestSpawn mu zobraz tento dialog a použi return 0 (aby si zablokoval spawn).

    V OnDialogResponse potom môžeš spawnúť hráča cez SpawnPlayer a cez SetPlayerPos mu nastaviť pozíciu podľa vybraného listitemu.

    Na error týkajúci sa príkazov si radšej založ samostatný topic a ukáž nám tam svoj kód v OnPlayerCommandText.

  15. Prišiel som na to, kde bol problém.
    String cmd okrem parametrov obsahuje na začiatku aj názov príkazu. 
    Preto ti "s[65]i" nefungovalo a "s[6]s[65]i" už fungovalo.
     

    Tento názov príkazu nemusíš ukladať do premennej, ale môžeš použiť feature sscanf2: "quiet" stringy. 
    Dočítať sa o nich môžeš tu.
    Napríklad takto to krásne funguje:
     

    Spoiler
    
    #define FILTERSCRIPT
    
    #include <a_samp>
    #include <sscanf2>
    
    public OnRconCommand(cmd[])
    {
        if (!strcmp(cmd, "addvip", true, 6))
        {
            printf("addvip executed");
    
            new playerName[65];
            new days;
            if (sscanf(cmd, "{s[128]}s[65]i", playerName, days))
            {
                printf("Usage: /rcon addvip [playerName] [days]");
                return 1;
            }
    
            printf("playerName='%s', days=%d", playerName, days);
    
            // mysql query, ...
            return 1;
        }
    
        if (!strcmp(cmd, "othercommand", true, 12))
        {
            printf("othercommand executed");
            return 1;
        }
    
        return 0;
    }
    

     

     

    • Líbí se mi to! (+1) 1
  16. před 1 hodinou, MichaelMik9 said:

    ale ten smysl, že následující kód jde a předchozí ne, mi to fakt nedává

    Pridáš sem aj výpis z logu s novým kódom? Nemyslím si, že ti to funguje tak, ako by si chcel.

    před 1 hodinou, MichaelMik9 said:

    if(strcmp(command, "addvip", true, 6))

    je pravdivé iba ak sa command nezhoduje s "addvip", takže pochybujem, že ti to teraz niečo po rcon príkaze addvip vkladá do databázy.

  17. před 20 minutami, Hip said:

    Víš jaký řádek tento runtime error způsobuje? Tipnul bych si že to je hned 

    
    mysql_query(Database, sqliteAddVip, false);

    V logu vidno hlášku "USE SYNTAX: addvip [name] [days]".
    Keďže sa vykonala else vetva, nehľadal by som crashujúci riadok v druhej vetve.

    Myslím si, že za crash môžu riadky:

    new playerVipName;
    new days;
    if(!sscanf(cmd, "s[65]i", playerVipName, days))

    Sscanf plugin sa pravdepodobne pokúšal natlačiť celý string "MichaelMik1" do premennej playerVipName, ktorá keď je definovaná týmto spôsobom, má iba 4 bajty.
    Tento string tam nevošiel a plugin zapisoval do pamäte za touto premennou, čo mohlo spôsobiť invalid memory access. 

    Preto by ma zaujímalo, či problém pretrváva, keď sa riadok new playerVipName; zmenil na new playerVipName[65];.

  18. před 3 hodinami, NuMeRe said:

    Samp WIki je známá a mnoho pawneru ji používá

    Možno si si nevšimol, že nejde o originálnu wiki, ale o jej kópiu na doméne blast.hk. Ja som napríklad o tejto kópii nevedel a som za tento príspevok vďačný, keďže originálna samp wiki už nie je dostupná ani cez wayback machine na archive.org.

    • Děkuji (+1) 1
    • Líbí se mi to! (+1) 2
  19. Vyhovuje ti f(n) = n * 0.55 / 1000 + 0.245? Teda napríklad pre y = 500 by bola výška postavy 500 * 0.55 / 1000 +  0.245 = 0.52.

    Dopracoval som sa k tomu pomocou sústavy 2 rovníc o 2 neznámych, ktoré vznikli dosadením tvojich bodov ([100;0.3] a [1100;0.85]) do všeobecného tvaru lineárnej funkcie (y = a * x + b):

    0.3 = a * 100 + b
    0.85 = a * 1100 + b
     

×
×
  • Create New...