# Metatable Functions

ดึง **metatable** ของค่าโดยไม่คำนึงถึงฟิลด์ **\_\_metatable** ของ **Value** นั้นๆ

```lua
<table> getrawmetatable(<table> value)
```

### ตัวอย่าง #1&#x20;

{% code lineNumbers="true" %}

```lua
-- ทำซ้ำโค้ดที่อยู่ภายในบล็อก while ในระหว่างรอ 1 วินาทีทุกครั้ง
while wait(1) do
    -- แสดงค่าของตัวแปร workspace.Camera ในคอนโซล (Console)
    print(workspace.Camera)
end
```

{% endcode %}

### ตัวอย่าง #2

{% code lineNumbers="true" %}

```lua
-- นำค่า metatable ของตัวแปร game มาเก็บในตัวแปร game_meta
local game_meta = getrawmetatable(game)

-- นำค่า __index ของ metatable มาเก็บในตัวแปร game_index
local game_index = game_meta.__index

-- ทำให้ metatable ของตัวแปร game เปลี่ยนแปลงค่าได้ (mutable) โดยใช้ setreadonly() โดยกำหนดให้เป็น false
setreadonly(game_meta, false) -- Required to avoid errors

-- กำหนดให้ตัวแปร game_meta เปลี่ยนแปลงค่าของ __index ใหม่โดยใช้ฟังก์ชัน (function) ที่กำหนดเอง
game_meta.__index = function(Instance, string)
    -- เมื่อมีการเรียกใช้ __index ของตัวแปร game_meta ด้วยตัวอักษร string

    -- ถ้า string คือ "Camera" ให้คืนค่าการเรียกใช้ __index ของ game โดยใช้ชื่อ Instance ของตัวแปร "Workspace"
    if string == "Camera" then
        return game_index(game, "Workspace")
    end

    -- หากไม่ใช่กรณีข้างต้น ให้คืนค่าการเรียกใช้ __index ของตัวแปร Instance ด้วยตัวอักษร string
    return game_index(Instance, string)
end
```

{% endcode %}

กำหนดตารางเมตาเทเบิลตัวแรกให้เป็นตารางที่ระบุ (provided mt) โดยไม่สนใจว่ามีฟิลด์ \_\_metatable อยู่ในตารางเมตาเทเบิลตัวแรกหรือไม่" ซึ่งเป็นคำอธิบายของการใช้งานภาษาโปรแกรม Lua ในสภาวะที่ต้องการกำหนดตารางเมตาเทเบิลของค่าให้เป็นตารางที่กำหนดไว้ โดยไม่สนใจว่าตารางเมตาเทเบิลตัวแรกมีฟิลด์ \_\_metatable อยู่หรือไม่

### Hook Metamethod

เชื่อมต่อ Metamethod ที่ระบุไว้ในตารางเมตาเทเบิลของ Object กับฟังก์ชัน f

```lua
<function> hookmetamethod(<Instance> Object, <string> Metamethod, <function> f)
```

### ตัวอย่าง

{% code lineNumbers="true" %}

```lua
-- ข้อควรทราบ: โค้ดด้านล่างนี้ไม่ควรนำไปใช้ในโปรเจคจริง เพราะอาจก่อให้เกิดปัญหาในการทำงานของเกม

-- ควรให้คำเตือนว่าโค้ดนี้เป็นเพียงตัวอย่างการใช้งานและไม่ควรนำไปใช้ในโปรเจคจริง

-- __namecall Hook
local OldNamecall
OldNamecall = hookmetamethod(game, "__namecall", function(self, ...)
    -- ก่อนจะทำอะไรกับ Metatable "__namecall" ก่อนหน้านี้
    -- คืนค่า Metatable "__namecall" ตัวเก่า (OldNamecall) และคืนค่าตามการเรียกใช้งาน (self, ...)
    return OldNamecall(self, ...)
end)

-- __index Hook
local OldIndex
OldIndex = hookmetamethod(game, "__index", function(self, i)
    -- ก่อนจะทำอะไรกับ Metatable "__index" ก่อนหน้านี้
    -- คืนค่า Metatable "__index" ตัวเก่า (OldIndex) และคืนค่าตามการเรียกใช้งาน (self, i)
    return OldIndex(self, i)
end)

-- __newindex Hook
local OldNewIndex
OldNewIndex = hookmetamethod(game, "__newindex", function(self, i, v)
    -- ก่อนจะทำอะไรกับเมทาเทเบิล "__newindex" ก่อนหน้านี้
    -- คืนค่า Metatable "__newindex" ตัวเก่า (OldNewIndex) และคืนค่าตามการเรียกใช้งาน (self, i, v)
    return OldNewIndex(self, i, v)
end)
```

{% endcode %}

### ตัวอย่าง : Basic Remote Spy

{% code lineNumbers="true" %}

```lua
-- คำเตือน : โค้ดด้านล่างนี้ไม่ควรนำไปใช้ในโปรเจคจริง

-- ควรให้คำเตือนว่าโค้ดนี้เป็นเพียงตัวอย่างการใช้งานและไม่ควรนำไปใช้ในโปรเจคจริง

-- namecalls คือฟังก์ชันที่ถูกเรียกใช้งานด้วย : (ตัวอย่างเช่น RemoteEvent:FireServer())
local old -- กำหนดตัวแปร old เพื่อเก็บชื่อเมทาเมธอดเดิม (ชื่อเก่า) เนื่องจากจะทำการ hook เพื่อตรวจสอบ (เพื่อป้องกันการเกิดข้อผิดพลาดในการเรียกใช้งานที่ถูกต้อง)
old = hookmetamethod(game, "__namecall", function(self, ...)
    -- self = อินสแตนซ์ของ Remote
    -- ... = อาร์กิวเมนต์ของเมทอด
    local args = {...}
    if getnamecallmethod() == "FireServer" then -- ตรวจสอบว่าเมทาเมธอดที่ถูกเรียกใช้เป็น "FireServer"
        local Path = self:GetFullName() -- ดึงชื่อเส้นทางของ Remote
        local Arguments = table.concat(args, "\n") -- รวม Argument เป็นสตริง
        print(string.format("Path: %s\nArguments:\n%s", Path, Arguments)) -- แสดงข้อมูลที่ตรวจสอบผ่านทางคอนโซล (Console) ซึ่งเป็นตัวอย่างเพียงอย่างง่าย
        -- การใช้งาน remote spies ที่แสดงผลในคอนโซลนั้นไม่ควรเป็นวิธีการที่ดี นี่เป็นเพียงตัวอย่างการใช้งาน
    end
    return old(self, ...) -- ส่งคืนการเรียกใช้งานเมธอดเดิม (ชื่อเก่า)
end)

```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xenon-hub.gitbook.io/seriality-roblox/seriality-dll/metatable-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
