Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 14
  1. #1
    Аватар для Prolific
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.12.2013
    Сообщений
    116
    Репутация:
    14 ±

    licenses.inc Система лицензий в битовой реализации

    На форуме почти в каждом уроке посвященному битовым операциям упоминается про систему лицензий, которую можно сделать с их помощью, но никто (по крайней мере я не видел) не делал конкретный пример, который можно подключить и пользоваться. Я написал инклуд, который использует всего 1 одномерный массив на MAX_PLAYERS ячеек, который и будет хранить все лицензии.

     Исходный код
    PHP код:
    #include <a_samp>

    stock licenses[MAX_PLAYERS];

    //Посмотреть лицензию
    #define GetLicCar(%0)             (licenses[%0] & 1 ? true : false)
    #define GetLicPlane(%0)           (licenses[%0] & (1<<1) ? true : false)
    #define GetLicShip(%0)            (licenses[%0] & (1<<2) ? true : false)
    #define GetLicBiz(%0)             (licenses[%0] & (1<<3) ? true : false)
    #define GetLicFish(%0)            (licenses[%0] & (1<<4) ? true : false)

    //Выдать лицензию
    #define GiveLicCar(%0)            (licenses[%0] |= 1)
    #define GiveLicPlane(%0)          (licenses[%0] |= (1<<1))
    #define GiveLicShip(%0)           (licenses[%0] |= (1<<2))
    #define GiveLicBiz(%0)            (licenses[%0] |= (1<<3))
    #define GiveLicFish(%0)           (licenses[%0] |= (1<<4))

    //Забрать лицензию
    #define TakeLicCar(%0)            (licenses[%0] &= ~1)
    #define TakeLicPlane(%0)          (licenses[%0] &= ~(1<<1))
    #define TakeLicShip(%0)           (licenses[%0] &= ~(1<<2))
    #define TakeLicBiz(%0)            (licenses[%0] &= ~(1<<3))
    #define TakeLicFish(%0)           (licenses[%0] &= ~(1<<4))

    #define GetPlayerLicsValue(%0)    licenses[%0]
    #define SetPlayerLicsValue(%0,%1) (licenses[%0] = %1) 


    Просто вставляем это в мод, либо подключаем в виде инклуда.

    P.S. Хранить в БД нужно всего 1-о число.
    Пример сохранения:
    PHP код:
    mysql_format(DATABASEstringsizeof(string), "UPDATE `accounts` SET `pLicenses` = %d  WHERE `pID` = %d LIMIT 1"
        
    GetPlayerLicsValue(playerid), pInfo[playerid][pID]); 
    Пример инициализации:
    PHP код:
    SetPlayerLicsValue(playeridcache_get_field_content_int(0"pLicenses"DATABASE)); 
    Последний раз редактировалось Prolific; 12.05.2016 в 19:30.

  2. 3 пользователя(ей) сказали cпасибо:
    Nexius_Tailer (12.05.2016) Unreal (19.05.2016) vovandolg (12.05.2016)
  3. #2
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Идея хорошая, но реализация, ИМХО, хромает.
    PHP код:
    #define GetLicCar(%0)             (licenses[%0] & 1 ? true : false)
    #define GetLicPlane(%0)           (licenses[%0] & (1<<1) ? true : false)
    #define GetLicShip(%0)            (licenses[%0] & (1<<2) ? true : false)
    #define GetLicBiz(%0)             (licenses[%0] & (1<<3) ? true : false)
    #define GetLicFish(%0)            (licenses[%0] & (1<<4) ? true : false) 
    Каждый новый макрос здесь - это повторение предыдущего. Разве что GetLicCar реализован не так, как остальные, но это может только ещё больше сбить с толку.

    Мало того, если какой-то вид лицензии не объявлен, мне придётся самому лезть в чужой код, разбираться, как он работает, и добавлять макросы для новых лицензий.
    Причём не факт, что эти новые макросы будут добавлены правильно. Если я сделаю макрос на основе уже существующего и забуду поменять название, компилятор выдаст варнинг на повторное определение макроса.
    Если же забыть поменять значение сдвига (например, вместо "<<5" оставить "<<4"), ошибка останется незамеченной.


    В общем, набросал я тут "эталонную" реализацию (кавычки потому, что не мне решать, насколько она эталонная).
    Не то, чтобы я хочу заставить вас использовать её в какой-то степени, но надеюсь, что вы изучите её, раз решили взяться за написание инклудов.
    PHP код:
    // Защита от повторного подключения (актуально при использовании модифицированного компилятора от Zeex).
    #if defined PL_LICENSES // Префикс "PL" - сокращение от "Prolific", можете выбрать и другой.
        #endinput
    #endif
    #define PL_LICENSES

    #include <a_samp>


    // Макросы для работы с флагами.
    #if !defined BitGet
        #define BitGet(%0,%1)\
            
    (%0) & (<< (%1))
    #endif
    #if !defined BitSet
        #define BitSet(%0,%1,%2)\
            
    %= ((%2) != 0) ? ((%0) | (<< (%1))) : ((%0) & ~(<< (%1)))
    #endif


    #if !defined e_LICENSE_TYPE
    // Допускаем возможность самостоятельного объявления лицензий на случай, если пользователю нужен тип лицензии,
    // которого нет в инклуде (например, здесь не объявлена лицензия на ведение бизнеса).
    enum e_LICENSE_TYPE
    {
        
    LICENSE_TYPE_FISHING,
        
    LICENSE_TYPE_DRIVING,
        
    LICENSE_TYPE_PILOT
    };
    #endif

    // Если типов лицензий не больше восьми, можно использовать упакованный массив.
    // Спецификатор static ограничивает видимость переменной в пределах инклуда.
    static stock licenses[MAX_PLAYERS char];


    // Функции для операций с лицензиями.
    // Здесь нужны именно функции, а не макросы, чтобы компилятор мог выдать варнинг,
    // если, например, вместо "LICENSE_TYPE_FISHING" передать "0".
    stock GetPlayerLicenseStatus(playeride_LICENSE_TYPE:type)
        return 
    BitGet(licenses{playerid}, _:type);

    stock SetPlayerLicenseStatus(playeride_LICENSE_TYPE:typebool:active)
        return 
    BitSet(licenses{playerid}, _:type_:active);

    stock GivePlayerLicense(playeride_LICENSE_TYPE:type)
        return 
    BitSet(licenses{playerid}, _:type1);

    stock TakePlayerLicense(playeride_LICENSE_TYPE:type)
        return 
    BitSet(licenses{playerid}, _:type0);

    stock GetPlayerLicenses(playerid)
        return 
    licenses{playerid};

    stock SetPlayerLicenses(playeridflags)
        return (
    licenses{playerid} = flags); 
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  4. Пользователь сказал cпасибо:
    L0ndl3m (12.05.2016)
  5. #3
    Аватар для L0ndl3m
    Пользователь

    Статус
    Оффлайн
    Регистрация
    19.10.2013
    Адрес
    Ярославль
    Сообщений
    1,366
    Репутация:
    774 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Код:
    #if !defined BitGet
    	#define BitGet(%0,%1)\
    		%0 &= (1 << (%1))
    #endif
    Ошибка? Получаем же значение флага.

  6. Пользователь сказал cпасибо:
    Daniel_Cortez (12.05.2016)
  7. #4
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Londlem Посмотреть сообщение
    Ошибка? Получаем же значение флага.
    Да, верно. Час ночи, что сказать... Хорошо хоть, что не релиз.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  8. #5
    Аватар для Prolific
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.12.2013
    Сообщений
    116
    Репутация:
    14 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Идея хорошая, но реализация, ИМХО, хромает.

    Каждый новый макрос здесь - это повторение предыдущего. Разве что GetLicCar реализован не так, как остальные, но это может только ещё больше сбить с толку.

    Мало того, если какой-то вид лицензии не объявлен, мне придётся самому лезть в чужой код, разбираться, как он работает, и добавлять макросы для новых лицензий.
    Причём не факт, что эти новые макросы будут добавлены правильно. Если я сделаю макрос на основе уже существующего и забуду поменять название, компилятор выдаст варнинг на повторное определение макроса.
    Если же забыть поменять значение сдвига (например, вместо "<<5" оставить "<<4"), ошибка останется незамеченной.


    В общем, набросал я тут "эталонную" реализацию (кавычки потому, что не мне решать, насколько она эталонная).
    Не то, чтобы я хочу заставить вас использовать её в какой-то степени, но надеюсь, что вы изучите её, раз решили взяться за написание инклудов.
    PHP код:
    // Защита от повторного подключения (актуально при использовании модифицированного компилятора от Zeex).
    #if defined PL_LICENSES // Префикс "PL" - сокращение от "Prolific", можете выбрать и другой.
        #endinput
    #endif
    #define PL_LICENSES

    #include <a_samp>


    // Макросы для работы с флагами.
    #if !defined BitGet
        #define BitGet(%0,%1)\
            
    (%0) & (<< (%1))
    #endif
    #if !defined BitSet
        #define BitSet(%0,%1,%2)\
            
    %= ((%2) != 0) ? ((%0) | (<< (%1))) : ((%0) & ~(<< (%1)))
    #endif


    #if !defined e_LICENSE_TYPE
    // Допускаем возможность самостоятельного объявления лицензий на случай, если пользователю нужен тип лицензии,
    // которого нет в инклуде (например, здесь не объявлена лицензия на ведение бизнеса).
    enum e_LICENSE_TYPE
    {
        
    LICENSE_TYPE_FISHING,
        
    LICENSE_TYPE_DRIVING,
        
    LICENSE_TYPE_PILOT
    };
    #endif

    // Если типов лицензий не больше восьми, можно использовать упакованный массив.
    // Спецификатор static ограничивает видимость переменной в пределах инклуда.
    static stock licenses[MAX_PLAYERS char];


    // Функции для операций с лицензиями.
    // Здесь нужны именно функции, а не макросы, чтобы компилятор мог выдать варнинг,
    // если, например, вместо "LICENSE_TYPE_FISHING" передать "0".
    stock GetPlayerLicenseStatus(playeride_LICENSE_TYPE:type)
        return 
    BitGet(licenses{playerid}, _:type);

    stock SetPlayerLicenseStatus(playeride_LICENSE_TYPE:typebool:active)
        return 
    BitSet(licenses{playerid}, _:type_:active);

    stock GivePlayerLicense(playeride_LICENSE_TYPE:type)
        return 
    BitSet(licenses{playerid}, _:type1);

    stock TakePlayerLicense(playeride_LICENSE_TYPE:type)
        return 
    BitSet(licenses{playerid}, _:type0);

    stock GetPlayerLicenses(playerid)
        return 
    licenses{playerid};

    stock SetPlayerLicenses(playeridflags)
        return (
    licenses{playerid} = flags); 
    В любом случае нужно лезть в инклуд для добавления значений в enum, либо выносить его в мод, но это уже противоречит твоей цели, DC. В целом твой вариант более гибкий, not bad.

    - - - Добавлено - - -

    P.S.
    // если, например, вместо "LICENSE_TYPE_FISHING" передать "0".
    Какая разница что мы передаем 0 или LICENSE_TYPE_FISHING?

  9. #6
    Аватар для TheMallard
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.12.2015
    Адрес
    San Fierro
    Сообщений
    217
    Репутация:
    39 ±
    А флаг зачем тогда придумывать? Да и в PlayerInfo можно 0 задействовать, не спорю.

  10. #7
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Prolific Посмотреть сообщение
    В любом случае нужно лезть в инклуд для добавления значений в enum, либо выносить его в мод, но это уже противоречит твоей цели, DC.
    Не нужно. Не зря ж объявление e_LICENSE_TYPE заключено в #if - если объявить такой тег до подключения инклуда, будет использоваться пользовательский набор лицензий.
    PHP код:
    enum e_LICENSE_TYPE
    {
        
    LICENSE_TYPE_FISHING,
        
    LICENSE_TYPE_DRIVING,
        
    LICENSE_TYPE_PILOT,
        
    LICENSE_TYPE_BUSINESS,
        
    LICENSE_TYPE_BOATING,
        
    LICENSE_TYPE_BREATH
    };
    #include "../include/licenses.inc" 


    Цитата Сообщение от Prolific Посмотреть сообщение
    P.S.
    // если, например, вместо "LICENSE_TYPE_FISHING" передать "0".
    Какая разница что мы передаем 0 или LICENSE_TYPE_FISHING?
    Ну вы ж не будете наизусть заучивать номера лицензий. Наверняка в вашем моде полно и других вещей, которые нужно постоянно держать в голове - зачем создавать себе ещё одну проблему?

    Никогда не понимал людей, которые спешат сэкономить каждую секунду и избегают использования констант, наивно думая, что им больше не придётся копаться в своём коде. И ведь ещё не факт, что они тратят меньше времени, ведь им приходится заучивать наизусть константы и отлавливать баги, которые у них возникают куда чаще из-за опечаток и перепутанных чисел.

    В то же время благодаря разным тегам можно осуществлять контроль над передаваемыми значениями: если на входе у функции не константа LICENSE_TYPE_*, то это, скорее всего, ошибка.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  11. Пользователь сказал cпасибо:
    Unreal (24.06.2016)
  12. #8
    Аватар для Prolific
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.12.2013
    Сообщений
    116
    Репутация:
    14 ±
    Где я сказал, что теги не нужны???!!! Я сказал лишь в чем разница и почему бы и нет, вы тут как всегда раздули из мухи слона, + показали свое ЧСВ, ведь естественно у всех гавнокод кроме вас любимых, относился всегда к этому с юмором, но тут что не ответ то показываение своего ЧСВ. Смотрите, а то так не заметите как Окстайлами станете.
    Последний раз редактировалось Prolific; 13.05.2016 в 18:31.

  13. #9
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Prolific Посмотреть сообщение
    Где я сказал, что теги не нужны???!!!
    Успокойтесь. Откуда мне знать, что именно вы знаете, а что нет?
    Поскольку я ещё не делал никаких уроков с описанием нюансов в плане создания инклудов, я постарался подробно ответить на вопрос в этой теме, да и не столько ради вас, сколько ради других пользователей, которые тоже могут подчерпнуть отсюда новых знаний. Зачем сразу так бурно реагировать?


    Цитата Сообщение от Prolific Посмотреть сообщение
    Я сказал лишь в чем разница и почему бы и нет, вы тут как всегда раздули из мухи слона, + показали свое ЧСВ, ведь естественно у всех гавнокод кроме вас любимых, относился всегда к этому с юмором, но тут что не ответ то показываение своего ЧСВ. Смотрите, а то так не заметите как Окстайлами станете.
    Если я выразил свою точку зрения, показав неэффективность подхода с избеганием именованных констант, это обязательно должно иметь какое-то отношение к моему ЧСВ?
    Впрочем, "говнокод" могло звучать действительно резко, но у меня и в мыслях даже не было такого, чтобы говнокод писали все, кроме меня - и не подумал бы никогда о такой интерпретации своих слов, если б вы об этом не написали. Исправил свой предыдущий пост.
    Тем не менее, муху из слона раздуваете вы, выискивая везде намёки на чьё-то ЧСВ и яростно реагируя на слово "говнокод" и излишнюю информацию (которая не факт, что адресована только вам).
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  14. #10
    Аватар для Prolific
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.12.2013
    Сообщений
    116
    Репутация:
    14 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Успокойтесь. Откуда мне знать, что именно вы знаете, а что нет?
    Поскольку я ещё не делал никаких уроков с описанием нюансов в плане создания инклудов, я постарался подробно ответить на вопрос в этой теме, да и не столько ради вас, сколько ради других пользователей, которые тоже могут подчерпнуть отсюда новых знаний. Зачем сразу так бурно реагировать?



    Если я выразил свою точку зрения, показав неэффективность подхода с избеганием именованных констант, это обязательно должно иметь какое-то отношение к моему ЧСВ?
    Впрочем, "говнокод" могло звучать действительно резко, но у меня и в мыслях даже не было такого, чтобы говнокод писали все, кроме меня - и не подумал бы никогда о такой интерпретации своих слов, если б вы об этом не написали. Исправил свой предыдущий пост.
    Тем не менее, муху из слона раздуваете вы, выискивая везде намёки на чьё-то ЧСВ и яростно реагируя на слово "говнокод" и излишнюю информацию (которая не факт, что адресована только вам).
    Раз часть текста адресована не мне, то я спокоен.
    (Подгарел пукан, приношу извинения)

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •