Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.36 KB | None | 0 0
  1. #include "pcap++/IPv4Layer.h"
  2. #include "pcap++/IPv6Layer.h"
  3. #include "pcap++/Packet.h"
  4. #include "pcap++/PcapLiveDevice.h"
  5. #include "pcap++/PcapLiveDeviceList.h"
  6. #include "pcap++/UdpLayer.h"
  7.  
  8. #include "gl/glew.h"
  9. #include "gl/glu.h"
  10. #include "glm/glm.hpp"
  11. #include "glm/gtc/matrix_transform.hpp"
  12. #include "glm/gtc/type_ptr.hpp"
  13.  
  14. #include "SDL/SDL.h"
  15. #include "SDL/SDL_opengl.h"
  16. #include "unet.hpp"
  17. #include "common.hpp"
  18.  
  19. #include "tk.hpp"
  20. #include "tk_net.hpp"
  21.  
  22. #include <mutex>
  23. #include <memory>
  24. #include <thread>
  25. #include <unordered_map>
  26.  
  27. #define GLT_IMPLEMENTATION
  28. #include "gltext.h"
  29.  
  30. // vvv FILL THIS IN
  31. #define RADAR_IP "10.9.0.2"
  32. #define GAMERIG_IP "10.9.0.56"
  33.  
  34. struct Packet
  35. {
  36. int timestamp;
  37. bool outbound;
  38. std::vector<uint8_t> data;
  39. std::string src_ip;
  40. std::string dst_ip;
  41. };
  42.  
  43. struct WorkGroup
  44. {
  45. std::mutex work_guard;
  46. std::vector<Packet> work;
  47. };
  48.  
  49. struct GraphicsState
  50. {
  51. SDL_GLContext ctx;
  52. SDL_Window* window;
  53.  
  54. GLuint shader;
  55. GLuint vao;
  56. GLuint vbo;
  57. GLuint line_vao;
  58. GLuint line_vbo;
  59.  
  60. int width;
  61. int height;
  62. };
  63.  
  64. std::mutex g_world_lock;
  65.  
  66. void do_net(std::vector<Packet> work, const char* packet_dump_path);
  67. void do_update();
  68. void do_render(GraphicsState* state);
  69.  
  70. GraphicsState make_gfx(SDL_GLContext ctx, SDL_Window* window);
  71. void resize_gfx(GraphicsState* state, int width, int height);
  72.  
  73. int main(int argc, char* argv[])
  74. {
  75. const char* packet_dump_path = argc >= 2 ? argv[1] : nullptr;
  76. bool dump_packets = argc >= 3 && argv[2][0] == '1';
  77.  
  78. static int s_base_time = GetTickCount();
  79. static float time_scale = argc >= 4 ? atof(argv[3]) : 1.0f;
  80.  
  81. std::unique_ptr<std::thread> processing_thread;
  82. pcpp::PcapLiveDevice* dev = nullptr;
  83.  
  84. WorkGroup work;
  85.  
  86. if (packet_dump_path && !dump_packets)
  87. {
  88. // We load packets for offline replay on another thread.
  89. processing_thread = std::make_unique<std::thread>(
  90. [packet_dump_path, &work]()
  91. {
  92. FILE* file = fopen(packet_dump_path, "rb");
  93.  
  94. bool outbound;
  95. while (fread(&outbound, sizeof(outbound), 1, file) == 1)
  96. {
  97. int timestamp;
  98. fread(&timestamp, 4, 1, file);
  99.  
  100. int size;
  101. fread(&size, 4, 1, file);
  102.  
  103. std::vector<uint8_t> packet;
  104. packet.resize(size);
  105. fread(packet.data(), size, 1, file);
  106.  
  107. static int s_first_packet_time = timestamp;
  108.  
  109. while ((GetTickCount() - s_base_time) * time_scale < (uint32_t)timestamp - s_first_packet_time)
  110. {
  111. std::this_thread::yield(); // sleep might be better? doesn't matter much
  112. }
  113.  
  114. std::lock_guard<std::mutex> lock(work.work_guard);
  115. work.work.push_back({ timestamp, outbound, std::move(packet) });
  116. }
  117.  
  118. fclose(file);
  119. });
  120. }
  121. else
  122. {
  123. dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(RADAR_IP);
  124. dev->open();
  125.  
  126. pcpp::ProtoFilter filter(pcpp::UDP);
  127. dev->setFilter(filter);
  128.  
  129. static std::string s_server_ip;
  130.  
  131. dev->startCapture(
  132. [](pcpp::RawPacket* packet, pcpp::PcapLiveDevice* dev, void* user_data)
  133. {
  134. pcpp::Packet parsed(packet);
  135.  
  136. std::string src_ip;
  137. std::string dst_ip;
  138.  
  139. if (pcpp::IPv4Layer* ip = parsed.getLayerOfType<pcpp::IPv4Layer>())
  140. {
  141. src_ip = ip->getSrcIpAddress().toString();
  142. dst_ip = ip->getDstIpAddress().toString();
  143. }
  144. else if (pcpp::IPv6Layer* ip = parsed.getLayerOfType<pcpp::IPv6Layer>())
  145. {
  146. src_ip = ip->getSrcIpAddress().toString();
  147. dst_ip = ip->getDstIpAddress().toString();
  148. }
  149.  
  150. pcpp::UdpLayer* udp = parsed.getLayerOfType<pcpp::UdpLayer>();
  151. int len = udp->getDataLen() - udp->getHeaderLen();
  152. uint8_t* data_start = udp->getDataPtr(udp->getHeaderLen());
  153.  
  154. int timestamp = (int)(GetTickCount() - s_base_time);
  155. bool outbound = src_ip == GAMERIG_IP;
  156. std::vector<uint8_t> data;
  157. data.resize(len);
  158. memcpy(data.data(), data_start, len);
  159.  
  160. WorkGroup& work = *(WorkGroup*)user_data;
  161. std::lock_guard<std::mutex> lock(work.work_guard);
  162. work.work.push_back({ timestamp , outbound, std::move(data), std::move(src_ip), std::move(dst_ip) });
  163. }, &work);
  164. }
  165.  
  166. SDL_Init(SDL_INIT_EVERYTHING);
  167.  
  168. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  169. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
  170. SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  171.  
  172. SDL_Window* win = SDL_CreateWindow("Bastian Suter's Queef", 100, 100, 1920, 1080, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
  173. SDL_GLContext ctx = SDL_GL_CreateContext(win);
  174.  
  175. glewInit();
  176. SDL_GL_SetSwapInterval(1);
  177.  
  178. GraphicsState gfx = make_gfx(ctx, win);
  179.  
  180. bool quit = false;
  181.  
  182. std::unique_ptr<std::thread> net_thread = std::make_unique<std::thread>(
  183. [&]()
  184. {
  185. while (!quit)
  186. {
  187. std::vector<Packet> local_work;
  188.  
  189. {
  190. std::lock_guard<std::mutex> lock(work.work_guard);
  191. std::swap(local_work, work.work);
  192. }
  193.  
  194. if (!local_work.empty())
  195. {
  196. do_net(std::move(local_work), dump_packets ? packet_dump_path : nullptr);
  197. }
  198. else
  199. {
  200. SDL_Delay(10);
  201. }
  202. }
  203. });
  204.  
  205. while (!quit)
  206. {
  207. SDL_Event e;
  208. if (SDL_PollEvent(&e))
  209. {
  210. if (e.type == SDL_QUIT)
  211. {
  212. quit = true;
  213. }
  214. else if (e.type == SDL_WINDOWEVENT)
  215. {
  216. if (e.window.event == SDL_WINDOWEVENT_RESIZED)
  217. {
  218. resize_gfx(&gfx, e.window.data1, e.window.data2);
  219. }
  220. }
  221. }
  222.  
  223. do_update();
  224. do_render(&gfx);
  225. }
  226.  
  227. net_thread->join();
  228. gltTerminate();
  229.  
  230. SDL_GL_DeleteContext(ctx);
  231. SDL_DestroyWindow(win);
  232.  
  233. if (processing_thread)
  234. {
  235. processing_thread->join();
  236. }
  237.  
  238. if (dev)
  239. {
  240. dev->stopCapture();
  241. dev->close();
  242. }
  243.  
  244. return 0;
  245. }
  246.  
  247. struct FragmentedMessage
  248. {
  249. int parts;
  250. std::vector<std::unique_ptr<std::vector<uint8_t>>> packets;
  251. };
  252.  
  253. static std::unordered_map<int, FragmentedMessage> messages;
  254.  
  255. void do_net(std::vector<Packet> work, const char* packet_dump_path)
  256. {
  257. auto write_packet = [packet_dump_path](Packet& packet)
  258. {
  259. if (packet_dump_path)
  260. {
  261. FILE* file = fopen(packet_dump_path, "ab");
  262. fwrite(&packet.outbound, sizeof(packet.outbound), 1, file);
  263. fwrite(&packet.timestamp, 4, 1, file);
  264. int len = (int)packet.data.size();
  265. fwrite(&len, 4, 1, file);
  266. fwrite(packet.data.data(), len, 1, file);
  267. fclose(file);
  268. }
  269. };
  270.  
  271. static std::unique_ptr<UNET::AcksCache> s_inbound_acks;
  272. static std::unique_ptr<UNET::AcksCache> s_outbound_acks; // Technically it would be better to read acks from recieved packets for outbound
  273.  
  274. for (Packet& packet : work)
  275. {
  276. if (packet.data.size() <= 3)
  277. {
  278. // Too short for us to care about. Proceed.
  279. continue;
  280. }
  281.  
  282. uint8_t* data_start = packet.data.data();
  283. int data_len = (int)packet.data.size();
  284.  
  285. if (uint16_t conn_id = UNET::decodeConnectionId(data_start); !conn_id)
  286. {
  287. // This is a system message. We don't want to process it.
  288. if (data_start[2] == UNET::kConnect)
  289. {
  290. s_inbound_acks = std::make_unique<UNET::AcksCache>("INBOUND");
  291. s_outbound_acks = std::make_unique<UNET::AcksCache>("OUTBOUND");
  292.  
  293. std::lock_guard<std::mutex> lock(g_world_lock);
  294.  
  295. // This is a connection attempt. Let's establish a state.
  296. tk::g_state = std::make_unique<tk::GlobalState>();
  297. tk::g_state->server_ip = packet.dst_ip.empty() ? "LOCAL_REPLAY" : packet.dst_ip;
  298. tk::g_state->loot_db = std::make_unique<tk::LootDatabase>("items.json");
  299. }
  300.  
  301. write_packet(packet);
  302. continue;
  303. }
  304.  
  305. bool no_state = tk::g_state == nullptr;
  306. bool no_server = no_state || tk::g_state->server_ip.empty();
  307. bool filtered_out = no_server ||
  308. ( tk::g_state->server_ip != packet.src_ip &&
  309. tk::g_state->server_ip != packet.dst_ip &&
  310. tk::g_state->server_ip != "LOCAL_REPLAY");
  311.  
  312. if (filtered_out)
  313. {
  314. continue;
  315. }
  316.  
  317. write_packet(packet);
  318. // Now we strip the UNET-isms...
  319.  
  320. UNET::NetPacketHeader* packet_hdr = reinterpret_cast<UNET::NetPacketHeader*>(data_start);
  321. decodeNetPacketHeader(packet_hdr);
  322. data_start += sizeof(UNET::NetPacketHeader);
  323. data_len -= sizeof(UNET::NetPacketHeader);
  324.  
  325. UNET::PacketAcks128* acks = reinterpret_cast<UNET::PacketAcks128*>(data_start);
  326. // probably need to decode??
  327. data_start += sizeof(UNET::PacketAcks128);
  328. data_len -= sizeof(UNET::PacketAcks128);
  329.  
  330. UNET::AcksCache* received_acks = packet.outbound ? s_outbound_acks.get() : s_inbound_acks.get();
  331.  
  332. UNET::MessageExtractor messageExtractor((char*)data_start, data_len, 3 + (102*2), received_acks);
  333. while (messageExtractor.GetNextMessage())
  334. {
  335. std::unique_ptr<std::vector<uint8_t>> complete_message;
  336.  
  337. {
  338. uint8_t* user_data = (uint8_t*)messageExtractor.GetMessageStart();
  339. int user_len = messageExtractor.GetMessageLength();
  340. int channel = messageExtractor.GetChannelId();
  341.  
  342. if (channel == 0 || channel == 1 || channel == 2) // ReliableFragmented
  343. {
  344. UNET::NetMessageFragmentedHeader* hr = reinterpret_cast<UNET::NetMessageFragmentedHeader*>(user_data);
  345. UNET::decode(hr);
  346. user_data += sizeof(UNET::NetMessageFragmentedHeader);
  347. user_len -= sizeof(UNET::NetMessageFragmentedHeader);
  348.  
  349. std::unique_ptr<std::vector<std::uint8_t>> data = std::make_unique<std::vector<std::uint8_t>>();
  350. data->resize(user_len);
  351. memcpy(data->data(), user_data, user_len);
  352. int key = hr->fragmentedMessageId | channel << 8;
  353. messages[key].parts = hr->fragmentAmnt;
  354. messages[key].packets.resize(hr->fragmentAmnt);
  355.  
  356. if (hr->fragmentIdx >= messages[key].packets.size())
  357. {
  358. // broken fragment
  359. }
  360. else
  361. {
  362. messages[key].packets[hr->fragmentIdx] = std::move(data);
  363. }
  364.  
  365. bool complete = true;
  366.  
  367. for (int i = 0; i < hr->fragmentAmnt; ++i)
  368. {
  369. if (!messages[key].packets[i])
  370. {
  371. complete = false;
  372. break;
  373. }
  374. }
  375.  
  376. if (complete)
  377. {
  378. for (int i = 1; i < hr->fragmentAmnt; ++i)
  379. {
  380. messages[key].packets[0]->insert(
  381. std::end(*messages[key].packets[0]),
  382. std::begin(*messages[key].packets[i]),
  383. std::end(*messages[key].packets[i]));
  384. }
  385.  
  386. complete_message = std::move(messages[key].packets[0]);
  387. messages.erase(key);
  388. }
  389. }
  390. else
  391. {
  392. if (channel % 2 == 1)
  393. {
  394. UNET::NetMessageReliableHeader* hr = reinterpret_cast<UNET::NetMessageReliableHeader*>(user_data);
  395. decode(hr);
  396. if (!received_acks->ReadMessage(hr->messageId))
  397. {
  398. continue;
  399. }
  400. }
  401.  
  402. // channel % 2 == 0 does not have NetMessageReliableHeader but skip same bytes so this works
  403. user_data += sizeof(UNET::NetMessageReliableHeader);
  404. user_data += sizeof(UNET::NetMessageOrderedHeader);
  405. user_len -= sizeof(UNET::NetMessageReliableHeader);
  406. user_len -= sizeof(UNET::NetMessageOrderedHeader);
  407. complete_message = std::make_unique<std::vector<uint8_t>>();
  408. complete_message->resize(user_len);
  409. memcpy(complete_message->data(), user_data, user_len);
  410. }
  411. }
  412.  
  413. if (complete_message)
  414. {
  415. tk::ByteStream str(complete_message->data(), (int)complete_message->size());
  416. tk::process_packet(&str, messageExtractor.GetChannelId(), packet.outbound);
  417. }
  418. }
  419. }
  420. }
  421.  
  422. void do_update()
  423. {
  424. }
  425.  
  426. void do_render(GraphicsState* gfx)
  427. {
  428. // ye who read this code, judge its performance (and lack of state caching) not
  429. std::lock_guard<std::mutex> lock(g_world_lock);
  430.  
  431. glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
  432. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  433.  
  434. if (tk::g_state && tk::g_state->map)
  435. {
  436. glm::mat4 view = glm::mat4(1.0f);
  437. glm::mat4 projection = glm::mat4(1.0f);
  438.  
  439. projection = glm::perspective(glm::radians(75.0f), (float)gfx->width / (float)gfx->height, 0.1f, 2000.0f);
  440.  
  441. // flip x axis, from right handed (gl) to left handed (unity)
  442. projection = glm::scale(projection, glm::vec3(-1.0f, 1.0f, 1.0f));
  443.  
  444. auto get_forward_vec = [](float pitch, float yaw, glm::vec3 pos)
  445. {
  446. float elevation = glm::radians(-pitch);
  447. float heading = glm::radians(yaw);
  448. glm::vec3 forward_vec(cos(elevation) * sin(heading), sin(elevation), cos(elevation) * cos(heading));
  449. return forward_vec;
  450. };
  451.  
  452. auto get_alpha_for_y = [](float y1, float y2)
  453. {
  454. return abs(y1 - y2) >= 3.0f ? 63 : 255;
  455. };
  456.  
  457. tk::g_state->map->lock();
  458.  
  459. float player_y = 0.0f;
  460. glm::vec3 player_forward_vec;
  461.  
  462. if (tk::Observer* player = tk::g_state->map->get_player_manual_lock(); player)
  463. {
  464. player_y = player->pos.y;
  465. float pitch = player->rot.y;
  466. float yaw = player->rot.x;
  467. glm::vec3 cam_at(player->pos.x, player->pos.y + 1.5f, player->pos.z);
  468. player_forward_vec = get_forward_vec(pitch, yaw, cam_at);
  469. glm::vec3 cam_look = cam_at + player_forward_vec;
  470. view = glm::lookAt(cam_at, cam_look, { 0.0f, 1.0f, 0.0f });
  471.  
  472. glUseProgram(gfx->shader);
  473. glUniform1f(glGetUniformLocation(gfx->shader, "player_y"), player_y);
  474. glUniformMatrix4fv(glGetUniformLocation(gfx->shader, "projection"), 1, GL_FALSE, &projection[0][0]);
  475. glUniformMatrix4fv(glGetUniformLocation(gfx->shader, "view"), 1, GL_FALSE, &view[0][0]);
  476.  
  477. auto draw_text = [&gfx]
  478. (float x, float y, float z, float scale, const char* txt, int r, int g, int b, int a, glm::mat4* view, glm::mat4* proj)
  479. {
  480. GLTtext* text = gltCreateText();
  481. gltSetText(text, txt);
  482. gltBeginDraw();
  483. gltColor(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
  484. gltDrawText3D(text, x - gltGetTextWidth(text, scale) * 0.5f, y, z, scale, (GLfloat*)&view[0][0], (GLfloat*)&proj[0][0]);
  485. gltDeleteText(text);
  486. };
  487.  
  488. auto draw_box = [&gfx]
  489. (float x, float y, float z, float scale_x, float scale_y, float scale_z, int r, int g, int b)
  490. {
  491. glm::mat4 model = glm::mat4(1.0f);
  492. glm::vec3 pos(x, y, z);
  493. model = glm::translate(model, pos) * glm::scale(model, glm::vec3(scale_x, scale_y, scale_z));
  494. glUseProgram(gfx->shader);
  495. glUniform1i(glGetUniformLocation(gfx->shader, "line"), 0);
  496. glUniform1f(glGetUniformLocation(gfx->shader, "obj_y"), y - (scale_y / 2.0f));
  497. glUniform3f(glGetUniformLocation(gfx->shader, "color"), r / 255.0f, g / 255.0f, b / 255.0f);
  498. glUniformMatrix4fv(glGetUniformLocation(gfx->shader, "model"), 1, GL_FALSE, &model[0][0]);
  499. glBindVertexArray(gfx->vao);
  500. glBindBuffer(GL_ARRAY_BUFFER, gfx->vbo);
  501. glDrawArrays(GL_TRIANGLES, 0, 36);
  502. };
  503.  
  504. auto draw_line = [&gfx]
  505. (float x, float y, float z, float to_x, float to_y, float to_z, int r, int g, int b, int a)
  506. {
  507. float vertices[] = {
  508. x, y, z,
  509. to_x, to_y, to_z,
  510. };
  511.  
  512. glUseProgram(gfx->shader);
  513. glUniform1i(glGetUniformLocation(gfx->shader, "line"), a);
  514. glUniform3f(glGetUniformLocation(gfx->shader, "color"), r / 255.0f, g / 255.0f, b / 255.0f);
  515. glBindBuffer(GL_ARRAY_BUFFER, gfx->line_vbo);
  516. glBindVertexArray(gfx->line_vao);
  517. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
  518. glDrawArrays(GL_LINES, 0, 2);
  519. };
  520.  
  521. static std::unordered_map<std::string, std::tuple<uint8_t, uint8_t, uint8_t>> s_group_map; // maybe reset on map change?
  522.  
  523. for (tk::Observer* obs : tk::g_state->map->get_observers_manual_lock())
  524. {
  525. if (obs->type == tk::Observer::Self)
  526. {
  527. glm::vec3 at(obs->pos.x, obs->pos.y, obs->pos.z);
  528. glm::vec3 look = at + (get_forward_vec(obs->rot.y, obs->rot.x, at) * 50.0f);
  529. look.y += 1.5f;
  530. draw_line(at.x, at.y, at.z, look.x, look.y, look.z, 0, 255, 0, 255);
  531. continue;
  532. }
  533.  
  534. uint8_t r = 0;
  535. uint8_t g = 0;
  536. uint8_t b = 0;
  537.  
  538. float scale_x = 1.0f;
  539. float scale_y = 2.0f;
  540. float scale_z = 1.0f;
  541.  
  542. if (obs->is_unspawned)
  543. {
  544. r = 179;
  545. g = 120;
  546. b = 211;
  547. }
  548. else
  549. {
  550. if (obs->is_dead)
  551. {
  552. scale_x = 2.0f;
  553. scale_y = 1.0f;
  554. }
  555.  
  556. if (obs->type == tk::Observer::Scav && obs->is_npc)
  557. {
  558. r = 255;
  559. g = obs->is_dead ? 140 : 255;
  560. }
  561. else
  562. {
  563. r = obs->is_dead ? 139 : 255;
  564. }
  565. }
  566.  
  567. if (!obs->group_id.empty())
  568. {
  569. if (obs->group_id == player->group_id)
  570. {
  571. r = 0;
  572. g = 255;
  573. b = 0;
  574. }
  575. else if (auto entry = s_group_map.find(obs->group_id); entry == std::end(s_group_map))
  576. {
  577. s_group_map[obs->group_id] = std::make_tuple(rand() % 256, rand() % 256, rand() % 256);
  578. }
  579. }
  580.  
  581. if (!obs->is_dead && !obs->is_unspawned)
  582. {
  583. glm::vec3 at(obs->pos.x, obs->pos.y, obs->pos.z);
  584. glm::vec3 enemy_forward_vec = get_forward_vec(obs->rot.y, obs->rot.x, at);
  585. bool facing_towards_player = glm::dot(player_forward_vec, enemy_forward_vec) < -0.0f;
  586. int alpha = facing_towards_player ? 255 : 63;
  587. glm::vec3 look = at + (enemy_forward_vec * (facing_towards_player ? 75.0f : 12.5f));
  588. draw_line(at.x, at.y, at.z, look.x, look.y, look.z, r, g, b, alpha);
  589. }
  590.  
  591. draw_box(obs->pos.x, obs->pos.y, obs->pos.z, scale_x, scale_y, scale_z, r, g, b);
  592. }
  593.  
  594. for (Vector3* pos : tk::g_state->map->get_static_corpses_manual_lock())
  595. {
  596. draw_box(pos->x, pos->y, pos->z, 2.0f, 1.0f, 1.0f, 102, 0, 102);
  597. }
  598.  
  599. std::vector<std::pair<Vector3, std::string>> loot_text_to_render;
  600.  
  601. auto draw_loot = [&](tk::LootEntry* entry, bool include_equipment = true)
  602. {
  603. // This is where you insert your loot highlighting logic.
  604. draw_box(entry->pos.x, entry->pos.y, entry->pos.z, 0.5f, 0.5f, 0.5f, entry->container ? 255 : 0, entry->container ? 215 : 0, 0);
  605. };
  606.  
  607. for (tk::LootEntry* entry : tk::g_state->map->get_loot_manual_lock())
  608. {
  609. draw_loot(entry);
  610. }
  611.  
  612. for (tk::TemporaryLoot* entry : tk::g_state->map->get_temporary_loots_manual_lock())
  613. {
  614. draw_box(entry->pos.x, entry->pos.y + 1.5f, entry->pos.z, 0.15f, 3.0f, 0.15f, 0, 200, 200);
  615. draw_box(entry->pos.x, entry->pos.y, entry->pos.z, 0.25f, 0.25f, 0.25f, 0, 200, 200);
  616. }
  617.  
  618. for (tk::Observer* obs : tk::g_state->map->get_observers_manual_lock())
  619. {
  620. if (obs->type == tk::Observer::ObserverType::Self)
  621. {
  622. continue;
  623. }
  624.  
  625. int r = 255;
  626. int g = 255;
  627. int b = 255;
  628.  
  629. if (auto entry = s_group_map.find(obs->group_id); entry != std::end(s_group_map))
  630. {
  631. r = std::get<0>(entry->second);
  632. g = std::get<1>(entry->second);
  633. b = std::get<2>(entry->second);
  634. }
  635.  
  636. glm::vec3 player_pos(player->pos.x, player->pos.y, player->pos.z);
  637. glm::vec3 obs_pos(obs->pos.x, obs->pos.y, obs->pos.z);
  638. draw_text(obs->pos.x, obs->pos.y + 3.0f, obs->pos.z, 0.25f, std::to_string((int)glm::length(obs_pos - player_pos)).c_str(), r, g, b, get_alpha_for_y(player_y, obs->pos.y), &view, &projection);
  639. draw_text(obs->pos.x, obs->pos.y + 2.0f, obs->pos.z, 0.05f, obs->name.c_str(), r, g, b, get_alpha_for_y(player_y, obs->pos.y), &view, &projection);
  640. }
  641.  
  642. for (auto& [pos, txt] : loot_text_to_render)
  643. {
  644. draw_text(pos.x, pos.y + 0.5f, pos.z, 0.05f, txt.c_str(), 255, 215, 0, get_alpha_for_y(player_y, pos.y), &view, &projection);
  645. }
  646. }
  647.  
  648. tk::g_state->map->unlock();
  649. }
  650.  
  651. SDL_GL_SwapWindow(gfx->window);
  652. SDL_Delay(33);
  653. }
  654.  
  655. GraphicsState make_gfx(SDL_GLContext ctx, SDL_Window* window)
  656. {
  657. gltInit();
  658.  
  659. GraphicsState gfx;
  660. gfx.ctx = ctx;
  661. gfx.window = window;
  662. gfx.shader = glCreateProgram();
  663.  
  664. auto make_shader = [](GLuint type, const char* shader) -> GLuint
  665. {
  666. GLuint handle = glCreateShader(type);
  667. glShaderSource(handle, 1, &shader, NULL);
  668. glCompileShader(handle);
  669.  
  670. int success;
  671. glGetShaderiv(handle, GL_COMPILE_STATUS, &success);
  672. if (!success)
  673. {
  674. char info[512];
  675. glGetShaderInfoLog(handle, 512, NULL, info);
  676. };
  677.  
  678. return handle;
  679. };
  680.  
  681. GLuint vtx_shader = make_shader(GL_VERTEX_SHADER,
  682. R"(
  683. #version 330 core
  684. layout (location = 0) in vec3 aPos;
  685. layout (location = 1) in vec2 aTexCoord;
  686.  
  687. out float Alpha;
  688.  
  689. uniform mat4 model;
  690. uniform mat4 view;
  691. uniform mat4 projection;
  692. uniform int line;
  693. uniform float player_y;
  694. uniform float obj_y;
  695.  
  696. void main()
  697. {
  698. if (line > 0)
  699. {
  700. gl_Position = projection * view * vec4(aPos, 1.0f);
  701. Alpha = line / 255.0f;
  702. }
  703. else
  704. {
  705. gl_Position = projection * view * model * vec4(aPos, 1.0f);
  706. Alpha = abs(player_y - obj_y) >= 3.0f ? 0.25f : 1.0f;
  707. }
  708. }
  709. )"
  710. );
  711.  
  712. GLuint pixel_shader = make_shader(GL_FRAGMENT_SHADER,
  713. R"(
  714. #version 330 core
  715. out vec4 FragColor;
  716.  
  717. in float Alpha;
  718.  
  719. uniform vec3 color;
  720.  
  721. void main()
  722. {
  723. FragColor = vec4(color, Alpha);
  724. }
  725. )"
  726. );
  727.  
  728. glAttachShader(gfx.shader, vtx_shader);
  729. glAttachShader(gfx.shader, pixel_shader);
  730. glLinkProgram(gfx.shader);
  731.  
  732. float vertices[] = {
  733. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
  734. 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
  735. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  736. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  737. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
  738. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
  739.  
  740. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  741. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
  742. 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
  743. 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
  744. -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
  745. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  746.  
  747. -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  748. -0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  749. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  750. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  751. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  752. -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  753.  
  754. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  755. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  756. 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  757. 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  758. 0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  759. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  760.  
  761. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  762. 0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
  763. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
  764. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
  765. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  766. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  767.  
  768. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
  769. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  770. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  771. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  772. -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
  773. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
  774. };
  775.  
  776. glGenVertexArrays(1, &gfx.vao);
  777. glGenBuffers(1, &gfx.vbo);
  778. glBindVertexArray(gfx.vao);
  779. glBindBuffer(GL_ARRAY_BUFFER, gfx.vbo);
  780. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  781. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
  782. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
  783. glEnableVertexAttribArray(0);
  784. glEnableVertexAttribArray(1);
  785.  
  786. glGenVertexArrays(1, &gfx.line_vao);
  787. glGenBuffers(1, &gfx.line_vbo);
  788. glBindVertexArray(gfx.line_vao);
  789. glBindBuffer(GL_ARRAY_BUFFER, gfx.line_vbo);
  790. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
  791. glEnableVertexAttribArray(0);
  792.  
  793. glEnable(GL_DEPTH_TEST);
  794. glEnable(GL_BLEND);
  795. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  796.  
  797. int width;
  798. int height;
  799. SDL_GetWindowSize(gfx.window, &width, &height);
  800. resize_gfx(&gfx, width, height);
  801.  
  802. return gfx;
  803. }
  804.  
  805. void resize_gfx(GraphicsState* state, int width, int height)
  806. {
  807. glViewport(0, 0, width, height);
  808. state->width = width;
  809. state->height = height;
  810. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement