บอทสำหรับ Ragnarok Online เกี่ยวกับ พัฒนาสำหรับเซิร์ฟเวอร์ส่วนตัวRagna4th
วัตถุประสงค์ของโปรเจ็กต์นี้คือการเรียนรู้การวิศวกรรมย้อนกลับและ Windows API ใน Python ซึ่งเป็นซอฟต์แวร์ภายนอกที่อ่านหน่วยความจำเกมและส่งอินพุต
คุณสมบัติ มาโคร:มาโครที่เข้ารหัสแบบฮาร์ดโค้ดซึ่งรองรับการส่งคีย์สโตรกและคลิกเมาส์โดยตรงไปยังหน้าต่างเกม การคลิกเมาส์ไม่สามารถส่งไปยังตำแหน่งที่ระบุได้หากหน้าต่างไม่ได้อยู่ด้านบน แต่การคลิกนั้นได้รับการลงทะเบียนไว้ มีประโยชน์สำหรับการสแปมทักษะบนเท้าตัวละครของคุณในขณะที่กด Alt-Tab แมโครจะทำงานในเธรดแยกต่างหากเนื่องจากมีการหน่วงเวลาและสามารถเปิด/ปิดได้ ข้อมูลเกม:อ่านข้อมูลเกมที่จำเป็นในการดำเนินการ เช่น ชื่อตัวละคร ชื่อแผนที่ปัจจุบัน พิกัดแผนที่ HP ปัจจุบัน HP สูงสุด (อยู่ระหว่างดำเนินการ) การเดิน:เกมจะจัดเก็บข้อมูลแผนที่บางส่วนไว้ในไฟล์ .gat ไฟล์เหล่านี้ถูกแยกออกมาจากเกมและอ่านออกมาเพื่อสร้างกราฟที่แสดงให้เห็นว่าแต่ละเซลล์ของแผนที่สามารถเดินได้หรือไม่ แผนที่ส่วนใหญ่สามารถมีขนาดได้ถึง 400x400 แต่ข้อมูลนี้จะปรากฏอยู่ในไฟล์ .gat ด้วย รายการเอนทิตี้:อ่านเอนทิตี้ปัจจุบัน (ผู้เล่น, NPC, มอนสเตอร์...) บนหน้าจอ จะถูกใช้ในอนาคตเพื่อต่อสู้กับมอนสเตอร์ การคอมไพล์ไฟล์ c++ เป็น dll ไฟล์ c++ สามารถคอมไพล์ได้ด้วยคอมไพเลอร์ c++ ตัวใดก็ได้ ตราบใดที่แพลตฟอร์มเป้าหมายเป็น Windows แบบ 64 บิต
การใช้MSVCสามารถคอมไพล์ได้ดังนี้: cl.exe /LD /EHsc helpers/shortest_path.cpp
วาง dll ไว้ใน โฟลเดอร์ helpersคุณสามารถตรวจสอบว่าฟังก์ชันถูกส่งออกอย่างถูกต้องหรือไม่โดยใช้dumpbin /exports helpers/shortest_path.dll. ผลลัพธ์จะต้องส่งออกเป็นMy_ShortestPath.
เอกสารประกอบ ส่วนนี้จะประกอบด้วยเอกสารประกอบเกี่ยวกับกระบวนการย้อนวิศวกรรมเกม โดยกระบวนการย้อนวิศวกรรมทั้งหมดดำเนินการโดยใช้Cheat Engine 7.5 (CE) (เวอร์ชัน 32 บิต เนื่องจาก Ragnarok Online เป็นเวอร์ชัน 32 บิต) ไม่สามารถแนบโปรแกรมดีบักเกอร์เข้ากับกระบวนการเกมได้เนื่องจากGepard Shieldและโปรแกรมดีบักเกอร์ DBVM ของ CE ทำให้เกิด BSOD เมื่อโหลดเท่านั้น อาจเป็นเพราะฉันใช้ CPU ของ AMD
ผู้เล่นท้องถิ่น ค่าออฟเซ็ตของผู้เล่นในพื้นที่นั้นสามารถค้นหาได้โดยค้นหาค่าใน CE ค่าแรกคือชื่อผู้เล่น ชื่อแผนที่ปัจจุบัน พิกัด HP ปัจจุบัน และ HP สูงสุด ซึ่งค่อนข้างตรงไปตรงมา ด้านล่างนี้คือตัวอย่างค่าออฟเซ็ตคงที่ที่พบสำหรับพิกัด x ของผู้เล่น พิกัด x ของผู้เล่นท้องถิ่น ในกรณีนี้ ค่าแรกคือพิกัดผู้เล่นจริง ค่ากลางเปลี่ยนไปและไม่ตรงกับค่าที่ถูกต้องหลังจากผ่านไปสองสามวินาที จึงถูกละทิ้งไป ค่าสุดท้ายไม่ใช่พิกัดผู้เล่นจริง แต่เป็นพิกัดที่ผู้เล่นกำลังเคลื่อนที่ การใช้ค่านี้ส่งผลให้เกิดปัญหาเมื่อเคลื่อนย้ายตัวละคร เนื่องจากค่านี้ไม่ได้แสดงตำแหน่งของตัวละครแบบเรียลไทม์ ความแตกต่างระหว่างที่อยู่แรกและที่อยู่สุดท้ายสามารถมองเห็นได้โดยการย้ายตัวละคร ค่าแรกจะเปลี่ยนแปลงอย่างต่อเนื่องในขณะที่ตัวละครกำลังเคลื่อนที่ ในขณะที่ค่าสุดท้ายจะเปลี่ยนแปลงหนึ่งครั้งเมื่อคลิกตำแหน่งใหม่
โลก โลกเป็นโครงสร้างที่เก็บข้อมูลพื้นฐานทั้งหมดเพื่อให้เกมทำงานได้ เช่น ตัวชี้ไปยังผู้เล่นในพื้นที่และตัวชี้ไปยังรายการเอนทิตี โดยพบสิ่งนี้ขณะกำลังสแกนตัวชี้ในรายการเอนทิตี
ตัวตน เพื่อค้นหาที่อยู่ของเอนทิตี้ ฉันเริ่มต้นด้วยการโจมตีพวกมัน (เพื่อให้พวกมันติดตามตัวละครของฉัน) จากนั้นจึงค้นหาพิกัด x ของพวกมันใน CE ฉันเคลื่อนที่และค้นหาพิกัดใหม่จนกระทั่งมีที่อยู่เพียงไม่กี่แห่ง
เอนทิตี้ 1
ที่อยู่ในช่วง 0x18XXX ดูเหมือนจะไม่ใช่ส่วนหนึ่งของโครงสร้างเอนทิตี ทั้งหมดเป็นเพียงพิกัด x + อะไรสักอย่าง + พิกัด y ที่ล้อมรอบด้วยค่าที่ดูเหมือนจะไม่ใช่ส่วนหนึ่งของเอนทิตี
เอนทิตี้ 2
อย่างไรก็ตาม สองตัวสุดท้ายที่ไม่ใช่ตัวสุดท้ายก็ดูไม่ถูกต้องเช่นกัน เป็นเพียงพิกัด x และ y ที่ล้อมรอบด้วยข้อความมากมายซึ่งดูเหมือนข้อความแชทบนหน้าจอ
เอนทิตี้ 3
ตัวสุดท้ายคือตัวที่ถูกต้อง ค่ารอบ ๆ พิกัด x เปลี่ยนแปลงไปตามการโจมตีของมอนสเตอร์ และฉันสามารถเห็นค่า 1138 อยู่ด้านบนพิกัดสองสามไบต์ ซึ่งเป็น ID ของมอนสเตอร์ตาม ฐาน ข้อมูลเกม
เอนทิตี้ 4
หลังจากสแกนที่อยู่นี้ด้วยตัวชี้แล้ว ฉันสามารถเห็นว่าค่าออฟเซ็ตของพิกัด x คือ 0x16C หลังจากลองผิดลองถูกมาบ้าง ด้วยเหตุนี้ ฉันจึงสามารถค้นหาที่อยู่ฐานของสัตว์ประหลาดได้โดยค้นหาพิกัด x แล้วลบ 0x16C
เอนทิตี้ 5
รายชื่อนิติบุคคล หลังจากผ่านไปหลายชั่วโมง ก็พบรายการเอนทิตี้ ซึ่งเป็นรายการที่มีลิงก์คู่พร้อมตัวชี้ไปยังเอนทิตี้ทุกตัวบนหน้าจอ เอนทิตี้อาจเป็นผู้เล่น สัตว์ประหลาด NPC พอร์ทัล หรือสัตว์เลี้ยง (อาจเป็นสิ่งของอื่นๆ ได้อีก)
ในการค้นหารายการเอนทิตี้ ฉันเริ่มต้นด้วยการค้นหาที่อยู่ฐานของมอนสเตอร์บางตัวบนหน้าจอ จากนั้น ฉันสแกนพวกมันด้วยตัวชี้และเปรียบเทียบผลลัพธ์ หลังจากลองผิดลองถูกหลายครั้ง ฉันพบว่า [0xB3D1D4 + 0xCC] + 0x10 คือค่าที่ถูกต้อง รายการเอนทิตี้สามารถกำหนดได้ดังนี้:
struct EntityList { // Offset EntityList* next; // 0 EntityList* prev; // 4 Entity* entity; // 8 }; ตัวชี้แต่ละตัวจะชี้ไปยังโครงสร้างที่ยังไม่ทราบแน่ชัด แต่ค่าออฟเซ็ต 0x8 มักจะชี้ไปยังสิ่งที่เราเรียกว่าเอนทิตี้ในโปรเจ็กต์นี้ แอตทริบิวต์อื่นๆ จากโครงสร้างนี้ดูเหมือนจะมีข้อมูลสไปรต์และตัวชี้ไปยังโครงสร้าง HP ของมอนสเตอร์
รายชื่อนิติบุคคล 1 รายชื่อนิติบุคคล 2
แผนที่ ไฟล์.gat ถูกแยกออกมาจาก ไฟล์ data.grfของเกมโดยใช้โปรแกรมแก้ไข GRF นี้จากนั้นบทความนี้จาก Openkore wikiจะอธิบายวิธีการแยกไฟล์ หลังจากข้ามส่วนหัว (6 ไบต์) ความกว้างและความสูงของแผนที่จะถูกแยกออกมาจาก 8 ไบต์ถัดไป จากนั้น ส่วนที่เหลือของไฟล์จะถูกอ่านเป็นบล็อกขนาด 20 ไบต์ จากนั้นข้อมูลจะถูกแยกออกโดยใช้ไลบรารีstruct
ทำ [] เดินไปยังพิกัดนอกพื้นที่หน้าจอ โดยทั่วไปใช้ อัลกอริทึม A*เพื่อค้นหาเส้นทางที่สั้นที่สุดในกราฟแผนที่ที่อ่านจาก ไฟล์ .gatอาจใช้ทั้งใน Python และ C (โดยใช้Cython ) เพื่อเปรียบเทียบประสิทธิภาพ
[] หยิบสิ่งของจากพื้นดิน
[] การเดินจากที่ไหนก็ได้ไปยังที่ไหนก็ได้ อาจจะต้องดูไฟล์ Openkore เพื่อดูว่าข้อมูลเกี่ยวกับลิงก์แผนที่อยู่ที่ไหน (แผนที่ใดเชื่อมต่อกับแผนที่ใด)
[] การจัดเก็บ/ขายของอัตโนมัติ