Thursday, June 5, 2014

Dynamic / Fake Natives - Tạo thư viện cho Plugins của bạn


Xin lưu ý rằng hướng dẫn này là hướng về phía scripters trình độ trung cấp hoặc cao hơn. Nếu bạn là một người mới bắt đầu, điều này có thể gây nhầm lẫn bạn hoặc làm cho không có ý nghĩa.

Năng động / Fake Natives (tôi sẽ gọi chúng là động từ đây trở đi, tôi không thích giả từ khi họ thực sự làm một cái gì đó) cho phép bạn có các chức năng của một mô-đun (thông qua natives) bởi có một plugin mà hành động như một chạy mô-đun. Về lý thuyết, nó có thể toàn bộ module cổng fakemeta + plugin sử dụng nguyên tắc này (niềm vui đã được thực hiện, engine có thể được thực hiện với nhiều khó khăn). Từ kinh nghiệm của tôi, Natives năng động đi đôi với thiết kế API như trong tôi "Plugin API" hướng dẫn.

Dưới đây là những Natives được sử dụng cùng với Natives năng động:

  • register_native
  • register_library
  • get_param
  • get_param_byref
  • get_param_f
  • get_string
  • get_array
  • get_array_f
  • set_array
  • set_array_f
  • set_string
  • param_convert

Hãy ghi nhớ rằng Natives năng động là khá vô dụng khi không phải đối phó với nhiều hơn một plugin. Như vậy, các ví dụ sau đây sẽ luôn luôn có ít nhất 2 kịch bản, cộng với một bao gồm tập tin.

Đây là một ví dụ đơn giản để hiển thị các vấn đề cơ bản của Natives năng động:

Code:
#include <amxmodx> #include <fun> public plugin_init()     register_plugin("Dynamic Native Test - Handler","1.0","Hawk552")     public plugin_natives() {     register_library("dyn_test")         register_native("half_user_hp","_half_user_hp") } public _half_user_hp(iPlugin,iParams) {     if(iParams != 1)         return PLUGIN_CONTINUE             new id = get_param(1)     if(!id)         return PLUGIN_CONTINUE             set_user_health(id,get_user_health(id) / 2)         return PLUGIN_HANDLED }

Code:
#include <amxmodx> #include <dyn_test> public plugin_init()     register_plugin("Dynamic Native Test - Caller","1.0","Hawk552")     public client_putinserver(id)     if(is_user_alive(id))         half_user_hp(id)

Code:
// Tập tin này được gọi là dyn_test.inc (hoặc là bạn phải đổi tên #include <dyn_test> trong kịp bản 2) #pragma reqlib "dyn_test" native half_user_hp(id)

Bây giờ, những gì đang làm điều này? Về cơ bản, trên client_putinserver, nếu người dùng vẫn còn sống (trong đó chỉ đúng trong mods như chuồng sven nơi bạn sinh ra ngay) sau đó nó sẽ cắt HP của họ một nửa. Hãy chọn ngoài mỗi điều.

Mã 1

Lúc đầu chúng ta nhìn vào plugin_init, và chúng tôi nhận thấy không có gì đặc biệt. Sau đó chúng tôi nhìn xuống và thấy "plugin_natives", một phía trước hầu hết mọi người ở đây có lẽ không bao giờ thấy trước đây. Đây là nơi mà Natives và các thư viện phải được đăng ký. Đừng cố gắng để đặt chúng trong tiền đạo khác, như plugin_init hoặc plugin_precache.

Bây giờ, chúng ta hãy nhìn vào phần đầu tiên của plugin_natives, đó là register_library.

Điều này không làm những gì? Về cơ bản nó nói với amxx rằng plugin này cung cấp chức năng có nguồn gốc từ các plugin khác, và hỗ trợ với các lỗi " native not found để kiểm tra xem các plugin đã được nạp trước khi cố gắng gọi cho native động. Trong trường hợp này, chúng tôi kêu gọi thư viện của chúng tôi "dyn_test" cho "Dynamic Native Test". Có 2 loại của các thư viện trong amxx cốt lõi, như 1,75: thư viện và các lớp học. Một module là một thư viện, trong khi một plugin là một lớp. Thông tin này là hữu ích cho LibraryExists, mà sẽ được đề cập sau đó.

Tiếp theo, chúng ta thấy register_native.

const native[] - đây là tên của các native để đăng ký. Khá rõ ràng.
const handler[] - đây là tên của hàm sẽ được gọi khi bản địa này được sử dụng. Hãy nhớ rằng, nó phải được công khai (như với hầu hết các chức năng mà được đặt trong dấu ngoặc kép hay còn gọi là các nguồn bên ngoài)
[ style = 0 ] - điều này sẽ được giải thích

Bây giờ, khi chúng ta nhìn vào lời gọi register_native, chúng ta thấy xử lý là _half_user_hp. Vì vậy, chúng tôi nhìn xuống, và chúng ta thấy chức năng này.

Code:
public _half_user_hp(iPlugin,iParams)

Trong tất cả các navies dynamic, trừ khi đăng ký với style = 1, chúng ta thấy một cái gì đó để tác dụng của (id, params), mà tôi quyết định đổi tên trong tiêu đề. Param đầu tiên là plugin id - điều này rất hữu ích trong trường hợp bạn muốn gửi lại một callfunc hoặc một CreateOneForward / ExecuteForward, hoặc có một mảng lưu trữ dữ liệu cho mỗi plugin nạp. Param tiếp theo là iParams. Trong trường hợp ví dụ trên, iParams phải là 1, vì param chỉ là 1. Nếu đó là bất cứ điều gì khác nhau, một người nào đó quyết định ngu ngốc và sửa đổi tập tin bao gồm.

Tiếp theo, bên trong hàm, chúng tôi kiểm tra xem iParams == 1, và nếu nó không dừng lại ở đó chúng tôi. Tiếp theo, chúng tôi get_param (1), cho phép bạn để có được những thông số đầu tiên giả định đó là ô (mà nó là). Sau đó chúng tôi kiểm tra xem id là một số đếm, bởi vì chúng tôi không thể sử dụng 0 với get_user_health. Phần còn lại là khá tự giải thích.

Trong ví dụ này, tôi trở về PLUGIN_CONTINUE vì đó để đánh giá sai, và PLUGIN_HANDLED bởi vì nó đánh giá đúng sự thật. Điều này cho phép bạn làm kiểm tra lỗi đơn giản, ví dụ như "if (! Half_user_health (id)) log_amx (" failed ")".


Bây giờ handler là trên đường đi, chúng tôi nhận được xuống để các plugin sẽ sử dụng native dynamic này.

Đầu tiên, tôi muốn bạn nhìn vào các tập tin bao gồm (ví dụ 3). Điều đầu tiên chúng ta thấy là # pragma reqlib "dyn_test". Này có hiệu quả cho amxx "Nếu dyn_test không được tải, lỗi tôi ngay tại đây." Chức năng register_library trong ví dụ đầu tiên là những gì cho phép bạn bỏ qua điều này, bởi vì nó cho amxx mà dyn_test không tồn tại. Tiếp theo, trong cùng một tập tin này, chúng ta thấy half_user_hp native (id). Điều này về cơ bản cho các trình biên dịch mà half_user_hp sẽ được xử lý trong lớp VM (đó là nơi mà tất cả các C + + mã hóa là), nhưng lớp VM sẽ vượt qua nó xuống chức năng xử lý các native dynamic. Sau khi nó được xử lý, các lớp VM sẽ vượt qua kết quả trở lại để gọi hàm.

Lên kịch bản chính nó, chúng ta thấy rằng chúng tôi bao gồm tập tin này thông qua # include <dyn_test>. Phần còn lại là khá tự giải thích. 

Đối với các phần get_param, natives  trên (get_param_f, get_param_byref, vv) có thể được sử dụng để thay thế này, phụ thuộc vào những gì đối số được truyền vào hàm. 

Bây giờ, vào style = 1. style này về cơ bản quên về iPlugin, iParams một phần của tiêu đề, và sau đó giả định các plugin sẽ vượt qua các thông số chính xác. Điều này có nghĩa _half_user_hp sẽ như thế nào:

Code:
public _half_user_hp(id)

Cá nhân tôi không thích cách này là bạn không thể đảm bảo rằng các hàm gọi điện thoại gọi một cách chính xác, và cũng tất cả các mảng / chuỗi / ByRef thông số phải được chuyển đổi sử dụng param_convert, tuy nhiên nó là dễ dàng hơn cho navies đơn giản như trên.

Nếu bạn muốn thiết lập một chuỗi thông qua, mảng thông qua, hoặc thông qua ByRef tham số, sử dụng set_param, set_string, và set_array. Điều này về cơ bản cho phép bạn định dạng các thông số như thế nào định dạng nào, hoặc trong trường hợp của set_param nó cho phép bạn thiết lập một số (như trong cs_get_user_armor).


Tôi không thực sự muốn đẩy này nữa vì vậy tôi chỉ sẽ kết thúc ở đây. Như mọi khi, nếu bạn có bất kỳ câu hỏi hoặc nếu bất cứ điều gì tôi nói là sai, cảm thấy tự do để gửi.

0 nhận xét:

Post a Comment