diff --git a/API/server.js b/API/server.js
index 5d00c77..3ca426a 100644
--- a/API/server.js
+++ b/API/server.js
@@ -1,4 +1,5 @@
const express = require('express');
+const errorReporter = require('./utils/ErrorReporter');
const http = require('http');
const cors = require('cors');
const helmet = require('helmet');
@@ -57,6 +58,8 @@ app.use(cors({
}));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
+app.use(errorReporter.requestMiddleware());
+app.get('/health', (req, res) => res.json({ status: 'ok', service: 'API', ...errorReporter.getMetrics() }));
// Static file serving
app.use(express.static('../Website/dist'));
diff --git a/API/socket/socketHandlers.js b/API/socket/socketHandlers.js
deleted file mode 100644
index 0e046bf..0000000
--- a/API/socket/socketHandlers.js
+++ /dev/null
@@ -1,272 +0,0 @@
-const logger = require('../utils/logger');
-const { getGameSystem } = require('../systems/GameSystem');
-const Player = require('../models/Player');
-
-class SocketHandlers {
- constructor(io) {
- this.io = io;
- this.connectedUsers = new Map(); // userId -> socket.id
- this.userSockets = new Map(); // socket.id -> userId
- }
-
- handleConnection(socket) {
- logger.info(`Client connected: ${socket.id}`);
-
- // Authentication
- socket.on('authenticate', async (token) => {
- try {
- const jwt = require('jsonwebtoken');
- const decoded = jwt.verify(token, process.env.JWT_SECRET || 'fallback_secret');
-
- const player = await Player.findOne({ userId: decoded.userId });
- if (!player) {
- socket.emit('auth_error', { error: 'Player not found' });
- return;
- }
-
- // Store user connection
- this.connectedUsers.set(decoded.userId, socket.id);
- this.userSockets.set(socket.id, decoded.userId);
-
- socket.userId = decoded.userId;
- socket.emit('authenticated', { userId: decoded.userId });
-
- logger.info(`User authenticated: ${decoded.userId}`);
-
- // Join user to their current server if any
- if (player.currentServer) {
- socket.join(player.currentServer);
- this.broadcastToServer(player.currentServer, 'user_joined', {
- userId: decoded.userId,
- username: player.username
- });
- }
-
- } catch (error) {
- logger.error('Authentication error:', error);
- socket.emit('auth_error', { error: 'Invalid token' });
- }
- });
-
- // Server management
- socket.on('join_server', async (data) => {
- try {
- if (!socket.userId) {
- socket.emit('error', { error: 'Not authenticated' });
- return;
- }
-
- const gameSystem = getGameSystem();
- const server = await gameSystem.joinServer(data.serverId, socket.userId);
-
- // Update player's current server
- await Player.findOneAndUpdate(
- { userId: socket.userId },
- { currentServer: data.serverId }
- );
-
- // Join socket room
- socket.join(data.serverId);
-
- socket.emit('server_joined', { server });
- this.broadcastToServer(data.serverId, 'user_joined', {
- userId: socket.userId,
- serverId: data.serverId
- });
-
- logger.info(`User ${socket.userId} joined server ${data.serverId}`);
-
- } catch (error) {
- logger.error('Error joining server:', error);
- socket.emit('error', { error: error.message });
- }
- });
-
- socket.on('leave_server', async (data) => {
- try {
- if (!socket.userId) {
- socket.emit('error', { error: 'Not authenticated' });
- return;
- }
-
- const gameSystem = getGameSystem();
- const server = await gameSystem.leaveServer(data.serverId, socket.userId);
-
- // Update player's current server
- await Player.findOneAndUpdate(
- { userId: socket.userId },
- { currentServer: null }
- );
-
- // Leave socket room
- socket.leave(data.serverId);
-
- socket.emit('server_left', { server });
- this.broadcastToServer(data.serverId, 'user_left', {
- userId: socket.userId,
- serverId: data.serverId
- });
-
- logger.info(`User ${socket.userId} left server ${data.serverId}`);
-
- } catch (error) {
- logger.error('Error leaving server:', error);
- socket.emit('error', { error: error.message });
- }
- });
-
- // Game actions
- socket.on('game_action', async (data) => {
- try {
- if (!socket.userId) {
- socket.emit('error', { error: 'Not authenticated' });
- return;
- }
-
- const gameSystem = getGameSystem();
- const result = await gameSystem.processGameAction(socket.userId, data);
-
- socket.emit('action_result', { action: data.type, result });
-
- // Broadcast relevant actions to server
- if (data.broadcast && socket.userId) {
- const player = await Player.findOne({ userId: socket.userId });
- if (player && player.currentServer) {
- this.broadcastToServer(player.currentServer, 'user_action', {
- userId: socket.userId,
- username: player.username,
- action: data.type,
- result
- });
- }
- }
-
- } catch (error) {
- logger.error('Error processing game action:', error);
- socket.emit('error', { error: error.message });
- }
- });
-
- // Chat functionality
- socket.on('send_message', async (data) => {
- try {
- if (!socket.userId) {
- socket.emit('error', { error: 'Not authenticated' });
- return;
- }
-
- const player = await Player.findOne({ userId: socket.userId });
- if (!player || !player.currentServer) {
- socket.emit('error', { error: 'Not in a server' });
- return;
- }
-
- const message = {
- userId: socket.userId,
- username: player.username,
- message: data.message,
- timestamp: new Date(),
- type: data.type || 'chat'
- };
-
- // Broadcast to server
- this.broadcastToServer(player.currentServer, 'new_message', message);
-
- logger.info(`Chat message from ${socket.userId} in server ${player.currentServer}`);
-
- } catch (error) {
- logger.error('Error sending message:', error);
- socket.emit('error', { error: error.message });
- }
- });
-
- // Real-time updates
- socket.on('request_server_status', async () => {
- try {
- if (!socket.userId) {
- socket.emit('error', { error: 'Not authenticated' });
- return;
- }
-
- const player = await Player.findOne({ userId: socket.userId });
- if (!player || !player.currentServer) {
- socket.emit('server_status', { server: null });
- return;
- }
-
- const gameSystem = getGameSystem();
- const server = gameSystem.servers.get(player.currentServer);
-
- if (server) {
- const players = await Player.find({
- userId: { $in: server.players }
- }).select('userId username info.stats.level');
-
- socket.emit('server_status', {
- server: {
- id: server.id,
- name: server.name,
- currentPlayers: server.players.length,
- maxPlayers: server.maxPlayers,
- players: players.map(p => ({
- userId: p.userId,
- username: p.username,
- level: p.info.stats.level
- }))
- }
- });
- }
-
- } catch (error) {
- logger.error('Error getting server status:', error);
- socket.emit('error', { error: error.message });
- }
- });
-
- // Disconnection
- socket.on('disconnect', async () => {
- logger.info(`Client disconnected: ${socket.id}`);
-
- const userId = this.userSockets.get(socket.id);
- if (userId) {
- // Remove from tracking
- this.connectedUsers.delete(userId);
- this.userSockets.delete(socket.id);
-
- // Notify server if user was in one
- const player = await Player.findOne({ userId });
- if (player && player.currentServer) {
- this.broadcastToServer(player.currentServer, 'user_disconnected', {
- userId,
- username: player.username
- });
- }
- }
- });
- }
-
- broadcastToServer(serverId, event, data) {
- this.io.to(serverId).emit(event, data);
- }
-
- sendToUser(userId, event, data) {
- const socketId = this.connectedUsers.get(userId);
- if (socketId) {
- this.io.to(socketId).emit(event, data);
- }
- }
-
- broadcastToAll(event, data) {
- this.io.emit(event, data);
- }
-
- getConnectedUsers() {
- return Array.from(this.connectedUsers.keys());
- }
-
- getUserCount() {
- return this.connectedUsers.size;
- }
-}
-
-module.exports = SocketHandlers;
diff --git a/API/systems/EconomySystem.js b/API/systems/EconomySystem.js
deleted file mode 100644
index 5815d25..0000000
--- a/API/systems/EconomySystem.js
+++ /dev/null
@@ -1,385 +0,0 @@
-const logger = require('../utils/logger');
-
-class EconomySystem {
- constructor() {
- this.shopItems = {
- ships: [],
- weapons: [],
- armors: [],
- materials: [],
- consumables: []
- };
-
- this.dailyRewards = {
- baseReward: 100,
- consecutiveBonus: 50,
- maxConsecutiveDays: 30
- };
- }
-
- async initialize() {
- logger.info('Initializing Economy System...');
-
- // Initialize shop items
- await this.initializeShopItems();
-
- logger.info('Economy System initialized successfully');
- }
-
- async initializeShopItems() {
- // Ships
- this.shopItems.ships = [
- // Starter Cruiser Variants
- {
- id: 'starter_cruiser_common',
- name: 'Starter Cruiser',
- type: 'ship',
- rarity: 'common',
- price: 5000,
- currency: 'credits',
- description: 'Reliable starter cruiser for new pilots',
- texture: 'assets/textures/ships/starter_cruiser.png',
- stats: { attack: 15, speed: 10, defense: 12, hull: 100 }
- },
- {
- id: 'starter_cruiser_uncommon',
- name: 'Starter Cruiser II',
- type: 'ship',
- rarity: 'uncommon',
- price: 12000,
- currency: 'credits',
- description: 'Upgraded starter cruiser with enhanced systems',
- texture: 'assets/textures/ships/starter_cruiser.png',
- stats: { attack: 18, speed: 12, defense: 15, hull: 120 }
- },
- {
- id: 'starter_cruiser_rare',
- name: 'Starter Cruiser III',
- type: 'ship',
- rarity: 'rare',
- price: 25000,
- currency: 'credits',
- description: 'Elite starter cruiser with advanced weaponry',
- texture: 'assets/textures/ships/starter_cruiser.png',
- stats: { attack: 22, speed: 14, defense: 18, hull: 140 }
- },
- {
- id: 'starter_cruiser_epic',
- name: 'Starter Cruiser IV',
- type: 'ship',
- rarity: 'epic',
- price: 50000,
- currency: 'credits',
- description: 'Master starter cruiser with elite modifications',
- texture: 'assets/textures/ships/starter_cruiser.png',
- stats: { attack: 28, speed: 16, defense: 22, hull: 160 }
- },
- {
- id: 'starter_cruiser_legendary',
- name: 'Starter Cruiser V',
- type: 'ship',
- rarity: 'legendary',
- price: 100000,
- currency: 'credits',
- description: 'Legendary starter cruiser with unparalleled performance',
- texture: 'assets/textures/ships/starter_cruiser.png',
- stats: { attack: 35, speed: 18, defense: 28, hull: 180 }
- }
- ];
-
- // Weapons
- this.shopItems.weapons = [
- // Starter Blaster Variants
- {
- id: 'starter_blaster_common',
- name: 'Common Blaster',
- type: 'weapon',
- rarity: 'common',
- price: 1000,
- currency: 'credits',
- description: 'Basic blaster for new pilots',
- texture: 'assets/textures/weapons/starter_blaster.png',
- stats: { damage: 10, fireRate: 2, range: 5, energy: 5 }
- },
- {
- id: 'starter_blaster_uncommon',
- name: 'Starter Blaster II',
- type: 'weapon',
- rarity: 'uncommon',
- price: 2500,
- currency: 'credits',
- description: 'Improved blaster with better damage output',
- texture: 'assets/textures/weapons/starter_blaster.png',
- stats: { damage: 12, fireRate: 2.2, range: 5.5, energy: 6 }
- },
- {
- id: 'starter_blaster_rare',
- name: 'Starter Blaster III',
- type: 'weapon',
- rarity: 'rare',
- price: 5000,
- currency: 'credits',
- description: 'Advanced blaster with enhanced capabilities',
- texture: 'assets/textures/weapons/starter_blaster.png',
- stats: { damage: 15, fireRate: 2.5, range: 6, energy: 7 }
- },
- {
- id: 'starter_blaster_epic',
- name: 'Starter Blaster IV',
- type: 'weapon',
- rarity: 'epic',
- price: 10000,
- currency: 'credits',
- description: 'Elite blaster with superior performance',
- texture: 'assets/textures/weapons/starter_blaster.png',
- stats: { damage: 18, fireRate: 3, range: 6.5, energy: 8 }
- },
- {
- id: 'starter_blaster_legendary',
- name: 'Starter Blaster V',
- type: 'weapon',
- rarity: 'legendary',
- price: 20000,
- currency: 'credits',
- description: 'Legendary starter blaster with ultimate power',
- texture: 'assets/textures/weapons/starter_blaster.png',
- stats: { damage: 22, fireRate: 4, range: 7, energy: 10 }
- }
- ];
-
- // Armors
- this.shopItems.armors = [
- // Basic Armor Variants
- {
- id: 'basic_armor_common',
- name: 'Basic Armor',
- type: 'armor',
- rarity: 'common',
- price: 1500,
- currency: 'credits',
- description: 'Light protection for beginners',
- texture: 'assets/textures/armors/basic_armor.png',
- stats: { defense: 5, durability: 20, weight: 2, energyShield: 0 }
- },
- {
- id: 'basic_armor_uncommon',
- name: 'Basic Armor II',
- type: 'armor',
- rarity: 'uncommon',
- price: 4000,
- currency: 'credits',
- description: 'Improved basic armor with better durability',
- texture: 'assets/textures/armors/basic_armor.png',
- stats: { defense: 7, durability: 25, weight: 2.2, energyShield: 2 }
- },
- {
- id: 'basic_armor_rare',
- name: 'Basic Armor III',
- type: 'armor',
- rarity: 'rare',
- price: 8000,
- currency: 'credits',
- description: 'Enhanced armor with energy shielding',
- texture: 'assets/textures/armors/basic_armor.png',
- stats: { defense: 10, durability: 30, weight: 2.5, energyShield: 5 }
- },
- {
- id: 'basic_armor_epic',
- name: 'Basic Armor IV',
- type: 'armor',
- rarity: 'epic',
- price: 15000,
- currency: 'credits',
- description: 'Elite armor with advanced protection systems',
- texture: 'assets/textures/armors/basic_armor.png',
- stats: { defense: 15, durability: 35, weight: 3, energyShield: 10 }
- },
- {
- id: 'basic_armor_legendary',
- name: 'Basic Armor V',
- type: 'armor',
- rarity: 'legendary',
- price: 30000,
- currency: 'credits',
- description: 'Legendary armor with ultimate protection',
- texture: 'assets/textures/armors/basic_armor.png',
- stats: { defense: 20, durability: 40, weight: 3.5, energyShield: 15 }
- }
- ];
-
- // Materials
- this.shopItems.materials = [
- {
- id: 'iron_ore',
- name: 'Iron Ore',
- type: 'material',
- rarity: 'common',
- price: 50,
- currency: 'credits',
- description: 'Raw iron ore used for crafting basic weapons and armor',
- stackable: true
- },
- {
- id: 'copper_wire',
- name: 'Copper Wire',
- type: 'material',
- rarity: 'common',
- price: 75,
- currency: 'credits',
- description: 'Copper wiring used in electronic components',
- stackable: true
- },
- {
- id: 'energy_crystal',
- name: 'Energy Crystal',
- type: 'material',
- rarity: 'uncommon',
- price: 200,
- currency: 'credits',
- description: 'Crystallized energy used for powered equipment',
- stackable: true
- },
- {
- id: 'rare_metal',
- name: 'Rare Metal',
- type: 'material',
- rarity: 'rare',
- price: 500,
- currency: 'credits',
- description: 'Rare metallic alloy used for high-end crafting',
- stackable: true
- },
- {
- id: 'advanced_components',
- name: 'Advanced Components',
- type: 'material',
- rarity: 'rare',
- price: 1000,
- currency: 'credits',
- description: 'Sophisticated electronic components for advanced ship systems',
- stackable: true
- }
- ];
-
- // Consumables
- this.shopItems.consumables = [
- {
- id: 'health_kit',
- name: 'Health Kit',
- type: 'consumable',
- rarity: 'common',
- price: 100,
- currency: 'credits',
- description: 'A medical kit that restores health',
- consumable: true,
- effect: { health: 50 }
- },
- {
- id: 'energy_pack',
- name: 'Energy Pack',
- type: 'consumable',
- rarity: 'common',
- price: 150,
- currency: 'credits',
- description: 'A pack that restores energy',
- consumable: true,
- effect: { energy: 25 }
- },
- {
- id: 'repair_kit',
- name: 'Repair Kit',
- type: 'consumable',
- rarity: 'uncommon',
- price: 300,
- currency: 'credits',
- description: 'A kit that repairs ship damage',
- consumable: true,
- effect: { health: 100 }
- }
- ];
-
- logger.info(`Shop initialized with ${this.getTotalShopItems()} items`);
- }
-
- getTotalShopItems() {
- return Object.values(this.shopItems).reduce((total, category) => total + category.length, 0);
- }
-
- getShopItems(category = null) {
- if (category && this.shopItems[category]) {
- return this.shopItems[category];
- }
- return this.shopItems;
- }
-
- getItem(itemId) {
- for (const category of Object.values(this.shopItems)) {
- const item = category.find(item => item.id === itemId);
- if (item) return item;
- }
- return null;
- }
-
- purchaseItem(userId, itemId, quantity = 1) {
- const item = this.getItem(itemId);
- if (!item) {
- throw new Error('Item not found in shop');
- }
-
- const totalCost = item.price * quantity;
-
- return {
- item,
- quantity,
- totalCost,
- currency: item.currency
- };
- }
-
- calculateDailyReward(consecutiveDays) {
- const bonusMultiplier = Math.min(consecutiveDays - 1, this.dailyRewards.maxConsecutiveDays - 1);
- const bonusAmount = bonusMultiplier * this.dailyRewards.consecutiveBonus;
- const totalReward = this.dailyRewards.baseReward + bonusAmount;
-
- return {
- baseReward: this.dailyRewards.baseReward,
- consecutiveBonus: bonusAmount,
- totalReward,
- consecutiveDays
- };
- }
-
- getRandomShopItems(category, count = 6) {
- const items = this.shopItems[category] || [];
- const shuffled = [...items].sort(() => Math.random() - 0.5);
- return shuffled.slice(0, Math.min(count, items.length));
- }
-
- refreshShopInventory() {
- logger.info('Refreshing shop inventory...');
- // This would typically involve database operations
- // For now, we'll just log the refresh
- return true;
- }
-
- getShopStats() {
- const stats = {
- totalItems: this.getTotalShopItems(),
- itemsByCategory: {},
- averagePriceByCategory: {}
- };
-
- for (const [category, items] of Object.entries(this.shopItems)) {
- stats.itemsByCategory[category] = items.length;
-
- if (items.length > 0) {
- const totalPrice = items.reduce((sum, item) => sum + item.price, 0);
- stats.averagePriceByCategory[category] = Math.round(totalPrice / items.length);
- }
- }
-
- return stats;
- }
-}
-
-module.exports = EconomySystem;
diff --git a/API/systems/GameSystem.js b/API/systems/GameSystem.js
deleted file mode 100644
index 0279cc2..0000000
--- a/API/systems/GameSystem.js
+++ /dev/null
@@ -1,293 +0,0 @@
-const logger = require('../utils/logger');
-const Player = require('../models/Player');
-const Ship = require('../models/Ship');
-const Inventory = require('../models/Inventory');
-const Economy = require('./EconomySystem');
-
-class GameSystem {
- constructor() {
- this.players = new Map();
- this.servers = new Map();
- this.economy = new Economy();
- }
-
- async initializeGameSystems() {
- logger.info('Initializing server-side game systems...');
-
- // Initialize economy system
- await this.economy.initialize();
-
- logger.info('Game systems initialized successfully');
- }
-
- // Player management
- async createPlayer(userId, playerData) {
- try {
- const player = new Player({
- userId,
- ...playerData,
- createdAt: new Date(),
- lastLogin: new Date()
- });
-
- await player.save();
- this.players.set(userId, player);
-
- logger.info(`Created new player for user: ${userId}`);
- return player;
- } catch (error) {
- logger.error('Error creating player:', error);
- throw error;
- }
- }
-
- async loadPlayer(userId) {
- try {
- let player = this.players.get(userId);
-
- if (!player) {
- player = await Player.findOne({ userId }).populate('ships inventory');
- if (player) {
- this.players.set(userId, player);
- }
- }
-
- return player;
- } catch (error) {
- logger.error('Error loading player:', error);
- throw error;
- }
- }
-
- async savePlayer(userId) {
- try {
- const player = this.players.get(userId);
- if (player) {
- await player.save();
- logger.info(`Saved player data for user: ${userId}`);
- }
- } catch (error) {
- logger.error('Error saving player:', error);
- throw error;
- }
- }
-
- // Ship management
- async addShipToPlayer(userId, shipData) {
- try {
- const player = await this.loadPlayer(userId);
- if (!player) {
- throw new Error('Player not found');
- }
-
- const ship = new Ship({
- ...shipData,
- userId,
- acquiredAt: new Date()
- });
-
- await ship.save();
- player.ships.push(ship._id);
- await player.save();
-
- logger.info(`Added ship ${ship.name} to player ${userId}`);
- return ship;
- } catch (error) {
- logger.error('Error adding ship to player:', error);
- throw error;
- }
- }
-
- async equipShip(userId, shipId) {
- try {
- const player = await this.loadPlayer(userId);
- if (!player) {
- throw new Error('Player not found');
- }
-
- const ship = await Ship.findOne({ _id: shipId, userId });
- if (!ship) {
- throw new Error('Ship not found');
- }
-
- // Unequip current ship
- if (player.currentShip) {
- await Ship.findByIdAndUpdate(player.currentShip, { isEquipped: false });
- }
-
- // Equip new ship
- ship.isEquipped = true;
- await ship.save();
-
- player.currentShip = ship._id;
- await player.save();
-
- logger.info(`Equipped ship ${ship.name} for player ${userId}`);
- return ship;
- } catch (error) {
- logger.error('Error equipping ship:', error);
- throw error;
- }
- }
-
- // Server management
- async createServer(serverData) {
- try {
- const serverId = `server_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
-
- const server = {
- id: serverId,
- ...serverData,
- createdAt: new Date(),
- players: [],
- status: 'active'
- };
-
- this.servers.set(serverId, server);
- logger.info(`Created new server: ${serverId}`);
-
- return server;
- } catch (error) {
- logger.error('Error creating server:', error);
- throw error;
- }
- }
-
- async joinServer(serverId, userId) {
- try {
- const server = this.servers.get(serverId);
- if (!server) {
- throw new Error('Server not found');
- }
-
- if (server.players.length >= server.maxPlayers) {
- throw new Error('Server is full');
- }
-
- if (!server.players.includes(userId)) {
- server.players.push(userId);
- }
-
- logger.info(`Player ${userId} joined server ${serverId}`);
- return server;
- } catch (error) {
- logger.error('Error joining server:', error);
- throw error;
- }
- }
-
- async leaveServer(serverId, userId) {
- try {
- const server = this.servers.get(serverId);
- if (!server) {
- throw new Error('Server not found');
- }
-
- server.players = server.players.filter(id => id !== userId);
-
- if (server.players.length === 0) {
- this.servers.delete(serverId);
- logger.info(`Server ${serverId} deleted (no players)`);
- }
-
- logger.info(`Player ${userId} left server ${serverId}`);
- return server;
- } catch (error) {
- logger.error('Error leaving server:', error);
- throw error;
- }
- }
-
- getServerList() {
- return Array.from(this.servers.values()).map(server => ({
- id: server.id,
- name: server.name,
- type: server.type,
- maxPlayers: server.maxPlayers,
- currentPlayers: server.players.length,
- status: server.status,
- region: server.region,
- createdAt: server.createdAt
- }));
- }
-
- // Game actions
- async processGameAction(userId, actionData) {
- try {
- const player = await this.loadPlayer(userId);
- if (!player) {
- throw new Error('Player not found');
- }
-
- switch (actionData.type) {
- case 'dungeon_enter':
- return await this.handleDungeonEnter(player, actionData);
- case 'ship_upgrade':
- return await this.handleShipUpgrade(player, actionData);
- case 'item_purchase':
- return await this.handleItemPurchase(player, actionData);
- case 'daily_reward':
- return await this.handleDailyReward(player, actionData);
- default:
- throw new Error('Unknown action type');
- }
- } catch (error) {
- logger.error('Error processing game action:', error);
- throw error;
- }
- }
-
- async handleDungeonEnter(player, data) {
- // Dungeon logic will be implemented here
- logger.info(`Player ${player.userId} entering dungeon`);
- return { success: true, message: 'Dungeon entered' };
- }
-
- async handleShipUpgrade(player, data) {
- // Ship upgrade logic will be implemented here
- logger.info(`Player ${player.userId} upgrading ship`);
- return { success: true, message: 'Ship upgraded' };
- }
-
- async handleItemPurchase(player, data) {
- // Item purchase logic will be implemented here
- logger.info(`Player ${player.userId} purchasing item`);
- return { success: true, message: 'Item purchased' };
- }
-
- async handleDailyReward(player, data) {
- // Daily reward logic will be implemented here
- logger.info(`Player ${player.userId} claiming daily reward`);
- return { success: true, message: 'Daily reward claimed' };
- }
-}
-
-// Singleton instance
-let gameSystem = null;
-
-async function initializeGameSystems() {
- if (!gameSystem) {
- gameSystem = new GameSystem();
- try {
- await gameSystem.initializeGameSystems();
- } catch (error) {
- logger.error('Failed to initialize game systems:', error);
- throw error;
- }
- }
- return gameSystem;
-}
-
-function getGameSystem() {
- if (!gameSystem) {
- logger.warn('Game system not initialized. Call initializeGameSystems() first.');
- return null;
- }
- return gameSystem;
-}
-
-module.exports = {
- GameSystem,
- initializeGameSystems,
- getGameSystem
-};
diff --git a/API/utils/ErrorReporter.js b/API/utils/ErrorReporter.js
new file mode 100644
index 0000000..048d491
--- /dev/null
+++ b/API/utils/ErrorReporter.js
@@ -0,0 +1,119 @@
+/**
+ * GSO Error Reporter & Analytics (GDD Phase 3 — v3.2 lightweight implementation)
+ * Logs structured errors to file + provides in-memory analytics counters.
+ * Can be wired to external services (Sentry, Datadog) by replacing _sendToExternal().
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+class ErrorReporter {
+ constructor(options = {}) {
+ this.logDir = options.logDir || path.join(__dirname, '../logs');
+ this.service = options.service || 'GameServer';
+ this.env = process.env.NODE_ENV || 'development';
+ this.counters = {}; // event_type → count
+ this.errors = []; // last 100 errors in memory
+ this.maxErrors = 100;
+
+ // Ensure logs directory exists
+ if (!fs.existsSync(this.logDir)) {
+ fs.mkdirSync(this.logDir, { recursive: true });
+ }
+ }
+
+ // ── Error capture ──────────────────────────────────────────────────────────
+ captureError(err, context = {}) {
+ const entry = {
+ ts: new Date().toISOString(),
+ service: this.service,
+ env: this.env,
+ message: err?.message || String(err),
+ stack: err?.stack || null,
+ context,
+ };
+
+ // Store in memory ring buffer
+ this.errors.push(entry);
+ if (this.errors.length > this.maxErrors) this.errors.shift();
+
+ // Write to daily log file (non-blocking)
+ const logFile = path.join(this.logDir, `errors-${new Date().toISOString().slice(0,10)}.log`);
+ const line = JSON.stringify(entry) + '\n';
+ fs.appendFile(logFile, line, () => {}); // fire-and-forget
+
+ // Increment counter
+ this.increment('errors.total');
+
+ // Hook for external service (Sentry, etc.)
+ this._sendToExternal(entry);
+
+ return entry;
+ }
+
+ // ── Analytics event tracking ───────────────────────────────────────────────
+ track(event, data = {}) {
+ this.increment(event);
+ if (this.env === 'development') {
+ const logFile = path.join(this.logDir, `analytics-${new Date().toISOString().slice(0,10)}.log`);
+ fs.appendFile(logFile, JSON.stringify({ ts: new Date().toISOString(), event, data }) + '\n', () => {});
+ }
+ }
+
+ increment(key) {
+ this.counters[key] = (this.counters[key] || 0) + 1;
+ }
+
+ // ── Metrics snapshot ───────────────────────────────────────────────────────
+ getMetrics() {
+ return {
+ service: this.service,
+ uptime: Math.round(process.uptime()),
+ memoryMB: Math.round(process.memoryUsage().heapUsed / 1048576),
+ counters: { ...this.counters },
+ recentErrors: this.errors.slice(-10).map(e => ({ ts: e.ts, message: e.message, context: e.context })),
+ };
+ }
+
+ // ── Express middleware ─────────────────────────────────────────────────────
+ requestMiddleware() {
+ return (req, res, next) => {
+ const start = Date.now();
+ this.increment('http.requests');
+ res.on('finish', () => {
+ const ms = Date.now() - start;
+ this.increment(`http.${res.statusCode >= 400 ? 'errors' : 'success'}`);
+ if (ms > 2000) this.track('http.slow_request', { path: req.path, ms });
+ });
+ next();
+ };
+ }
+
+ errorMiddleware() {
+ return (err, req, res, next) => {
+ this.captureError(err, { path: req.path, method: req.method });
+ res.status(500).json({ error: 'Internal server error' });
+ };
+ }
+
+ // ── Socket.IO event tracking helper ───────────────────────────────────────
+ trackSocketEvent(eventName, userId) {
+ this.increment(`socket.${eventName}`);
+ this.increment('socket.total');
+ }
+
+ // ── External service stub ──────────────────────────────────────────────────
+ _sendToExternal(entry) {
+ // Replace with: Sentry.captureException(new Error(entry.message))
+ // or: axios.post(process.env.ERROR_WEBHOOK_URL, entry)
+ // Currently: no-op in development; log to console in production
+ if (this.env === 'production') {
+ console.error('[ErrorReporter]', entry.message, entry.context);
+ }
+ }
+}
+
+// Singleton
+const reporter = new ErrorReporter({ service: 'GameServer' });
+
+module.exports = reporter;
diff --git a/Client/index.html b/Client/index.html
index 8a5d698..d00a00e 100644
--- a/Client/index.html
+++ b/Client/index.html
@@ -1,4024 +1,8054 @@
+
+
+
+
+
Galaxy Strike Online - Space Idle MMORPG
+
+
+
+
+
+
+
+
+
+
+
Galaxy Strike Online
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
GALAXY STRIKE ONLINE
+
+
Initializing Universe...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fleet Status
+
+
+
+
+
Flagship: Starter Cruiser
+
Health: 100%
+
+
+
+
+
+
+
Idle Progress
+
+
Offline Time: 0h 0m
+
Resources Gained: 0
+
+
+
+
+
+
Player Stats
+
+
+
Level
+
1
+
+
+
Experience
+
0 / 500
+
+
+
+
+
Skill Points
+
0
+
+
+
Total XP Earned
+
0
+
+
+
Quests Completed
+
0
+
+
+
Last Login
+
Never
+
+
+
Total Kills
+
0
+
+
+
Dungeons Cleared
+
0
+
+
+
Play Time
+
0m 0s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Select a dungeon to begin your adventure
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Your Starbase
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🚀 Shipyard
+
Shipyard Level: 1 | Queue: 0/3
+
+
+
+
+
+
📋 Available Blueprints
+
+
+
+
+
+
+
⚙ Construction Queue
+
+
Slot 1 — Empty
+
Slot 2 — Empty
+
Slot 3 — Empty
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Daily quests reset in: 00:00:00
+
Weekly quests reset in: 0d 00:00
+
+
+
+
+
+
+
+
+
+
+
+
Ship Modules
+
Loading modules...
+
+
+
+
+
+
Select an item to view details
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Loading recipes...
+
+
+
+
+
+
Select a recipe
+
Choose a recipe from the list to see requirements and craft.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
⚗ Active Research Bonuses
+
+
+
+
+
Branches
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🏆 Commander Rankings
+
+
+
+
+
+
+
+
+
Select a category above to view rankings.
+
+
+
+
+
+
+
+
🚀 Fleet Missions
+
Send your ships on missions to earn resources, XP and loot. Missions run in real-time — check back to collect rewards.
+
+
+
+
+
+
+
+
+
+
+
+
+
📋 Mission Types
+
Loading…
+
+
+
🛸 Select Ships
+
+
+
+
+
+
+
+
+
⏱ Active Missions
+
+
+
+
+
+
+
+
+
+
+
+
📋 Available Faction Missions
+
Build reputation with NPC factions by completing their missions. Higher reputation unlocks better missions and discounts.
+
+
+
+
⏱ Active Faction Missions
+
+
No active faction missions
+
+
+
+
+
+
+
+
+
+
+
🛡 Alliance
+
+
+
+
+
+
+
🔍 Find Alliance
+
+
+
+
+
Search for alliances above
+
+
+
+
+
+
+
+
+
+
+
My Alliance
+
TAG
+
+
+
+
+
+
+
+
🏦 Alliance Warehouse
+
+
+
Deposit Resources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🏪 Player Market
+
Trade resources and items with other commanders. 2% listing fee. Listings expire after 24–72 hours.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
📦 List a Resource
+
+
+
+
+
+
+
+
+
+
+
🎒 List an Item
+
+
+
+
+
+
+
+
+
+
+
+
+
Loading your listings…
+
+
+
+
+
+
+
+
+
⚙ Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Reduced Motion (disables particles)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
👥 Social
+
+
+
+
+
+
-
-
🤝 Add Friend
-
-
-
-
-
-
📬 Friend Requests (0)
-
+
+
🤝 Add Friend
+
+
+
+
+
+
+
+
+
+
+
+
+
+
📬 Friend Requests (0)
+
+
+
+
+
+
+
+
👾 Friends (0 online)
+
+
+
+
+
+
+
+
+
🌐 Faction Reputation (GDD §15.3)
+
+
+
+
+
+
+
⚔ Combat Log (GDD §9.5)
+
+
+
+
No combat history yet
+
+
+
+
+
+
+
+
+
+
+
+
+
Initializing...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SELECT MODULE
+
+
+
+
+
+
+
+
No equippable items for this slot
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/locales/de.json b/Client/locales/de.json
index 36a5554..441e2ad 100644
--- a/Client/locales/de.json
+++ b/Client/locales/de.json
@@ -1 +1,62 @@
-{"_meta":{"lang":"de","name":"de","status":"placeholder - community translation needed"}}
+{
+ "_meta": {
+ "lang": "de",
+ "name": "Deutsch",
+ "version": "1.0"
+ },
+ "nav": {
+ "dashboard": "Dashboard",
+ "dungeons": "Dungeons",
+ "skills": "Fähigkeiten",
+ "base": "Basis",
+ "quests": "Aufgaben",
+ "inventory": "Inventar",
+ "crafting": "Herstellung",
+ "shop": "Laden",
+ "fleet": "Flotte",
+ "galaxy": "Galaxie",
+ "research": "Forschung",
+ "leaderboard": "Rangliste",
+ "missions": "Missionen",
+ "alliance": "Allianz",
+ "market": "Markt",
+ "social": "Sozial"
+ },
+ "base": {
+ "buildings": "🏗 Gebäude",
+ "shipyard": "🚀 Werft",
+ "starbase": "🌌 Sternenbasis",
+ "overview": "📊 Übersicht"
+ },
+ "resources": {
+ "metal": "Metall",
+ "gas": "Gas",
+ "crystal": "Kristall",
+ "energyCells": "Energiezellen",
+ "darkMatter": "Dunkle Materie",
+ "credits": "Credits",
+ "gems": "Edelsteine"
+ },
+ "actions": {
+ "build": "Bauen",
+ "upgrade": "Aufwerten",
+ "cancel": "Abbrechen",
+ "collect": "Einsammeln",
+ "launch": "Starten",
+ "search": "Suchen",
+ "join": "Beitreten",
+ "leave": "Verlassen",
+ "deposit": "Einzahlen",
+ "withdraw": "Abheben",
+ "buy": "Kaufen",
+ "sell": "Verkaufen"
+ },
+ "status": {
+ "online": "Online",
+ "offline": "Offline",
+ "inProgress": "In Arbeit",
+ "completed": "Abgeschlossen",
+ "locked": "Gesperrt",
+ "maxLevel": "Max. Level"
+ }
+}
\ No newline at end of file
diff --git a/Client/locales/es.json b/Client/locales/es.json
index 402a19e..7102e8c 100644
--- a/Client/locales/es.json
+++ b/Client/locales/es.json
@@ -1 +1,62 @@
-{"_meta":{"lang":"es","name":"es","status":"placeholder - community translation needed"}}
+{
+ "_meta": {
+ "lang": "es",
+ "name": "Español",
+ "version": "1.0"
+ },
+ "nav": {
+ "dashboard": "Panel",
+ "dungeons": "Mazmorras",
+ "skills": "Habilidades",
+ "base": "Base",
+ "quests": "Misiones",
+ "inventory": "Inventario",
+ "crafting": "Fabricación",
+ "shop": "Tienda",
+ "fleet": "Flota",
+ "galaxy": "Galaxia",
+ "research": "Investigación",
+ "leaderboard": "Clasificación",
+ "missions": "Misiones",
+ "alliance": "Alianza",
+ "market": "Mercado",
+ "social": "Social"
+ },
+ "base": {
+ "buildings": "🏗 Edificios",
+ "shipyard": "🚀 Astillero",
+ "starbase": "🌌 Base estelar",
+ "overview": "📊 Resumen"
+ },
+ "resources": {
+ "metal": "Metal",
+ "gas": "Gas",
+ "crystal": "Cristal",
+ "energyCells": "Células de energía",
+ "darkMatter": "Materia oscura",
+ "credits": "Créditos",
+ "gems": "Gemas"
+ },
+ "actions": {
+ "build": "Construir",
+ "upgrade": "Mejorar",
+ "cancel": "Cancelar",
+ "collect": "Recoger",
+ "launch": "Lanzar",
+ "search": "Buscar",
+ "join": "Unirse",
+ "leave": "Salir",
+ "deposit": "Depositar",
+ "withdraw": "Retirar",
+ "buy": "Comprar",
+ "sell": "Vender"
+ },
+ "status": {
+ "online": "En línea",
+ "offline": "Desconectado",
+ "inProgress": "En progreso",
+ "completed": "Completado",
+ "locked": "Bloqueado",
+ "maxLevel": "Nivel máx."
+ }
+}
\ No newline at end of file
diff --git a/Client/locales/fr.json b/Client/locales/fr.json
index 70ed77b..4ddcb6d 100644
--- a/Client/locales/fr.json
+++ b/Client/locales/fr.json
@@ -1 +1,62 @@
-{"_meta":{"lang":"fr","name":"fr","status":"placeholder - community translation needed"}}
+{
+ "_meta": {
+ "lang": "fr",
+ "name": "Français",
+ "version": "1.0"
+ },
+ "nav": {
+ "dashboard": "Tableau de bord",
+ "dungeons": "Donjons",
+ "skills": "Compétences",
+ "base": "Base",
+ "quests": "Quêtes",
+ "inventory": "Inventaire",
+ "crafting": "Artisanat",
+ "shop": "Boutique",
+ "fleet": "Flotte",
+ "galaxy": "Galaxie",
+ "research": "Recherche",
+ "leaderboard": "Classement",
+ "missions": "Missions",
+ "alliance": "Alliance",
+ "market": "Marché",
+ "social": "Social"
+ },
+ "base": {
+ "buildings": "🏗 Bâtiments",
+ "shipyard": "🚀 Chantier naval",
+ "starbase": "🌌 Base stellaire",
+ "overview": "📊 Vue d'ensemble"
+ },
+ "resources": {
+ "metal": "Métal",
+ "gas": "Gaz",
+ "crystal": "Cristal",
+ "energyCells": "Cellules d'énergie",
+ "darkMatter": "Matière noire",
+ "credits": "Crédits",
+ "gems": "Gemmes"
+ },
+ "actions": {
+ "build": "Construire",
+ "upgrade": "Améliorer",
+ "cancel": "Annuler",
+ "collect": "Collecter",
+ "launch": "Lancer",
+ "search": "Rechercher",
+ "join": "Rejoindre",
+ "leave": "Quitter",
+ "deposit": "Déposer",
+ "withdraw": "Retirer",
+ "buy": "Acheter",
+ "sell": "Vendre"
+ },
+ "status": {
+ "online": "En ligne",
+ "offline": "Hors ligne",
+ "inProgress": "En cours",
+ "completed": "Terminé",
+ "locked": "Verrouillé",
+ "maxLevel": "Niveau max"
+ }
+}
\ No newline at end of file
diff --git a/Client/locales/ja.json b/Client/locales/ja.json
index f867b19..8b4ba7d 100644
--- a/Client/locales/ja.json
+++ b/Client/locales/ja.json
@@ -1 +1,62 @@
-{"_meta":{"lang":"ja","name":"ja","status":"placeholder - community translation needed"}}
+{
+ "_meta": {
+ "lang": "ja",
+ "name": "日本語",
+ "version": "1.0"
+ },
+ "nav": {
+ "dashboard": "ダッシュボード",
+ "dungeons": "ダンジョン",
+ "skills": "スキル",
+ "base": "基地",
+ "quests": "クエスト",
+ "inventory": "インベントリ",
+ "crafting": "クラフト",
+ "shop": "ショップ",
+ "fleet": "艦隊",
+ "galaxy": "銀河",
+ "research": "研究",
+ "leaderboard": "ランキング",
+ "missions": "ミッション",
+ "alliance": "アライアンス",
+ "market": "マーケット",
+ "social": "ソーシャル"
+ },
+ "base": {
+ "buildings": "🏗 建物",
+ "shipyard": "🚀 造船所",
+ "starbase": "🌌 星間基地",
+ "overview": "📊 概要"
+ },
+ "resources": {
+ "metal": "金属",
+ "gas": "ガス",
+ "crystal": "クリスタル",
+ "energyCells": "エネルギーセル",
+ "darkMatter": "ダークマター",
+ "credits": "クレジット",
+ "gems": "ジェム"
+ },
+ "actions": {
+ "build": "建設",
+ "upgrade": "アップグレード",
+ "cancel": "キャンセル",
+ "collect": "収集",
+ "launch": "発射",
+ "search": "検索",
+ "join": "参加",
+ "leave": "退出",
+ "deposit": "入金",
+ "withdraw": "出金",
+ "buy": "購入",
+ "sell": "売却"
+ },
+ "status": {
+ "online": "オンライン",
+ "offline": "オフライン",
+ "inProgress": "進行中",
+ "completed": "完了",
+ "locked": "ロック中",
+ "maxLevel": "最大レベル"
+ }
+}
\ No newline at end of file
diff --git a/Client/locales/ko.json b/Client/locales/ko.json
index 2dace50..8d6d937 100644
--- a/Client/locales/ko.json
+++ b/Client/locales/ko.json
@@ -1 +1,62 @@
-{"_meta":{"lang":"ko","name":"ko","status":"placeholder - community translation needed"}}
+{
+ "_meta": {
+ "lang": "ko",
+ "name": "한국어",
+ "version": "1.0"
+ },
+ "nav": {
+ "dashboard": "대시보드",
+ "dungeons": "던전",
+ "skills": "스킬",
+ "base": "기지",
+ "quests": "퀘스트",
+ "inventory": "인벤토리",
+ "crafting": "제작",
+ "shop": "상점",
+ "fleet": "함대",
+ "galaxy": "은하계",
+ "research": "연구",
+ "leaderboard": "랭킹",
+ "missions": "미션",
+ "alliance": "동맹",
+ "market": "시장",
+ "social": "소셜"
+ },
+ "base": {
+ "buildings": "🏗 건물",
+ "shipyard": "🚀 조선소",
+ "starbase": "🌌 우주기지",
+ "overview": "📊 개요"
+ },
+ "resources": {
+ "metal": "금속",
+ "gas": "가스",
+ "crystal": "크리스탈",
+ "energyCells": "에너지 셀",
+ "darkMatter": "암흑 물질",
+ "credits": "크레딧",
+ "gems": "젬"
+ },
+ "actions": {
+ "build": "건설",
+ "upgrade": "업그레이드",
+ "cancel": "취소",
+ "collect": "수집",
+ "launch": "발사",
+ "search": "검색",
+ "join": "참가",
+ "leave": "나가기",
+ "deposit": "입금",
+ "withdraw": "출금",
+ "buy": "구매",
+ "sell": "판매"
+ },
+ "status": {
+ "online": "온라인",
+ "offline": "오프라인",
+ "inProgress": "진행 중",
+ "completed": "완료",
+ "locked": "잠김",
+ "maxLevel": "최대 레벨"
+ }
+}
\ No newline at end of file
diff --git a/Client/locales/pt.json b/Client/locales/pt.json
index 2119166..204a327 100644
--- a/Client/locales/pt.json
+++ b/Client/locales/pt.json
@@ -1 +1,62 @@
-{"_meta":{"lang":"pt","name":"pt","status":"placeholder - community translation needed"}}
+{
+ "_meta": {
+ "lang": "pt",
+ "name": "Português",
+ "version": "1.0"
+ },
+ "nav": {
+ "dashboard": "Painel",
+ "dungeons": "Masmorras",
+ "skills": "Habilidades",
+ "base": "Base",
+ "quests": "Missões",
+ "inventory": "Inventário",
+ "crafting": "Criação",
+ "shop": "Loja",
+ "fleet": "Frota",
+ "galaxy": "Galáxia",
+ "research": "Pesquisa",
+ "leaderboard": "Classificação",
+ "missions": "Missões",
+ "alliance": "Aliança",
+ "market": "Mercado",
+ "social": "Social"
+ },
+ "base": {
+ "buildings": "🏗 Edifícios",
+ "shipyard": "🚀 Estaleiro",
+ "starbase": "🌌 Base estelar",
+ "overview": "📊 Visão geral"
+ },
+ "resources": {
+ "metal": "Metal",
+ "gas": "Gás",
+ "crystal": "Cristal",
+ "energyCells": "Células de energia",
+ "darkMatter": "Matéria escura",
+ "credits": "Créditos",
+ "gems": "Gemas"
+ },
+ "actions": {
+ "build": "Construir",
+ "upgrade": "Melhorar",
+ "cancel": "Cancelar",
+ "collect": "Coletar",
+ "launch": "Lançar",
+ "search": "Pesquisar",
+ "join": "Entrar",
+ "leave": "Sair",
+ "deposit": "Depositar",
+ "withdraw": "Retirar",
+ "buy": "Comprar",
+ "sell": "Vender"
+ },
+ "status": {
+ "online": "Online",
+ "offline": "Offline",
+ "inProgress": "Em andamento",
+ "completed": "Concluído",
+ "locked": "Bloqueado",
+ "maxLevel": "Nível máx."
+ }
+}
\ No newline at end of file
diff --git a/Client/locales/zh.json b/Client/locales/zh.json
index 3edad9b..a481c98 100644
--- a/Client/locales/zh.json
+++ b/Client/locales/zh.json
@@ -1 +1,62 @@
-{"_meta":{"lang":"zh","name":"zh","status":"placeholder - community translation needed"}}
+{
+ "_meta": {
+ "lang": "zh",
+ "name": "中文",
+ "version": "1.0"
+ },
+ "nav": {
+ "dashboard": "仪表板",
+ "dungeons": "地下城",
+ "skills": "技能",
+ "base": "基地",
+ "quests": "任务",
+ "inventory": "背包",
+ "crafting": "制作",
+ "shop": "商店",
+ "fleet": "舰队",
+ "galaxy": "银河系",
+ "research": "研究",
+ "leaderboard": "排行榜",
+ "missions": "任务",
+ "alliance": "联盟",
+ "market": "市场",
+ "social": "社交"
+ },
+ "base": {
+ "buildings": "🏗 建筑",
+ "shipyard": "🚀 造船厂",
+ "starbase": "🌌 星际基地",
+ "overview": "📊 总览"
+ },
+ "resources": {
+ "metal": "金属",
+ "gas": "气体",
+ "crystal": "晶体",
+ "energyCells": "能量电池",
+ "darkMatter": "暗物质",
+ "credits": "积分",
+ "gems": "宝石"
+ },
+ "actions": {
+ "build": "建造",
+ "upgrade": "升级",
+ "cancel": "取消",
+ "collect": "收集",
+ "launch": "发射",
+ "search": "搜索",
+ "join": "加入",
+ "leave": "离开",
+ "deposit": "存入",
+ "withdraw": "提取",
+ "buy": "购买",
+ "sell": "出售"
+ },
+ "status": {
+ "online": "在线",
+ "offline": "离线",
+ "inProgress": "进行中",
+ "completed": "已完成",
+ "locked": "已锁定",
+ "maxLevel": "最高等级"
+ }
+}
\ No newline at end of file
diff --git a/GameServer/assets/images/armors/basic_armor.png b/GameServer/assets/images/armors/basic_armor.png
deleted file mode 100644
index b837e31..0000000
Binary files a/GameServer/assets/images/armors/basic_armor.png and /dev/null differ
diff --git a/GameServer/assets/images/armors/heavy_armor.png b/GameServer/assets/images/armors/heavy_armor.png
deleted file mode 100644
index 541fd8c..0000000
Binary files a/GameServer/assets/images/armors/heavy_armor.png and /dev/null differ
diff --git a/GameServer/assets/images/armors/medium_armor.png b/GameServer/assets/images/armors/medium_armor.png
deleted file mode 100644
index 2ad549a..0000000
Binary files a/GameServer/assets/images/armors/medium_armor.png and /dev/null differ
diff --git a/GameServer/assets/images/base/command_center.png b/GameServer/assets/images/base/command_center.png
deleted file mode 100644
index 0733bf5..0000000
Binary files a/GameServer/assets/images/base/command_center.png and /dev/null differ
diff --git a/GameServer/assets/images/base/mining_facility.png b/GameServer/assets/images/base/mining_facility.png
deleted file mode 100644
index 5898f23..0000000
Binary files a/GameServer/assets/images/base/mining_facility.png and /dev/null differ
diff --git a/GameServer/assets/images/items/consumables/bandages.png b/GameServer/assets/images/items/consumables/bandages.png
deleted file mode 100644
index 3ca78e8..0000000
Binary files a/GameServer/assets/images/items/consumables/bandages.png and /dev/null differ
diff --git a/GameServer/assets/images/items/consumables/health_pack.png b/GameServer/assets/images/items/consumables/health_pack.png
deleted file mode 100644
index 14694d8..0000000
Binary files a/GameServer/assets/images/items/consumables/health_pack.png and /dev/null differ
diff --git a/GameServer/assets/images/items/consumables/mega_health_pack.png b/GameServer/assets/images/items/consumables/mega_health_pack.png
deleted file mode 100644
index c12acc9..0000000
Binary files a/GameServer/assets/images/items/consumables/mega_health_pack.png and /dev/null differ
diff --git a/GameServer/assets/images/items/cosmetics/temp b/GameServer/assets/images/items/cosmetics/temp
deleted file mode 100644
index e69de29..0000000
diff --git a/GameServer/assets/images/items/materials/advanced_circuitboard.png b/GameServer/assets/images/items/materials/advanced_circuitboard.png
deleted file mode 100644
index 21b1421..0000000
Binary files a/GameServer/assets/images/items/materials/advanced_circuitboard.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/advanced_component.png b/GameServer/assets/images/items/materials/advanced_component.png
deleted file mode 100644
index 2e216a3..0000000
Binary files a/GameServer/assets/images/items/materials/advanced_component.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/advanced_components.png b/GameServer/assets/images/items/materials/advanced_components.png
deleted file mode 100644
index 2a71830..0000000
Binary files a/GameServer/assets/images/items/materials/advanced_components.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/basic_circuitboard.png b/GameServer/assets/images/items/materials/basic_circuitboard.png
deleted file mode 100644
index 7912445..0000000
Binary files a/GameServer/assets/images/items/materials/basic_circuitboard.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/battery.png b/GameServer/assets/images/items/materials/battery.png
deleted file mode 100644
index e024d52..0000000
Binary files a/GameServer/assets/images/items/materials/battery.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/common_circuitboard.png b/GameServer/assets/images/items/materials/common_circuitboard.png
deleted file mode 100644
index c60cde1..0000000
Binary files a/GameServer/assets/images/items/materials/common_circuitboard.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/copper_ore.png b/GameServer/assets/images/items/materials/copper_ore.png
deleted file mode 100644
index f6b6592..0000000
Binary files a/GameServer/assets/images/items/materials/copper_ore.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/copper_wire.png b/GameServer/assets/images/items/materials/copper_wire.png
deleted file mode 100644
index 82abfa3..0000000
Binary files a/GameServer/assets/images/items/materials/copper_wire.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/energy_crystal.png b/GameServer/assets/images/items/materials/energy_crystal.png
deleted file mode 100644
index 62abaf4..0000000
Binary files a/GameServer/assets/images/items/materials/energy_crystal.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/herbs.png b/GameServer/assets/images/items/materials/herbs.png
deleted file mode 100644
index c7d1e75..0000000
Binary files a/GameServer/assets/images/items/materials/herbs.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/iron_ore.png b/GameServer/assets/images/items/materials/iron_ore.png
deleted file mode 100644
index 6786de3..0000000
Binary files a/GameServer/assets/images/items/materials/iron_ore.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/leather.png b/GameServer/assets/images/items/materials/leather.png
deleted file mode 100644
index 55770b9..0000000
Binary files a/GameServer/assets/images/items/materials/leather.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/stell_plate.png b/GameServer/assets/images/items/materials/stell_plate.png
deleted file mode 100644
index 4bd086d..0000000
Binary files a/GameServer/assets/images/items/materials/stell_plate.png and /dev/null differ
diff --git a/GameServer/assets/images/items/materials/tin_bar.png b/GameServer/assets/images/items/materials/tin_bar.png
deleted file mode 100644
index a2daeac..0000000
Binary files a/GameServer/assets/images/items/materials/tin_bar.png and /dev/null differ
diff --git a/GameServer/assets/images/ships/heavy_cruiser.png b/GameServer/assets/images/ships/heavy_cruiser.png
deleted file mode 100644
index 38bcffa..0000000
Binary files a/GameServer/assets/images/ships/heavy_cruiser.png and /dev/null differ
diff --git a/GameServer/assets/images/ships/heavy_destroyer.png b/GameServer/assets/images/ships/heavy_destroyer.png
deleted file mode 100644
index a9366bd..0000000
Binary files a/GameServer/assets/images/ships/heavy_destroyer.png and /dev/null differ
diff --git a/GameServer/assets/images/ships/light_destroyer.png b/GameServer/assets/images/ships/light_destroyer.png
deleted file mode 100644
index 349c011..0000000
Binary files a/GameServer/assets/images/ships/light_destroyer.png and /dev/null differ
diff --git a/GameServer/assets/images/ships/starter_cruiser.png b/GameServer/assets/images/ships/starter_cruiser.png
deleted file mode 100644
index 2676b9d..0000000
Binary files a/GameServer/assets/images/ships/starter_cruiser.png and /dev/null differ
diff --git a/GameServer/assets/images/ui/icons/temp b/GameServer/assets/images/ui/icons/temp
deleted file mode 100644
index e69de29..0000000
diff --git a/GameServer/assets/images/ui/placeholder.png b/GameServer/assets/images/ui/placeholder.png
index b808c02..cd6a5ab 100644
Binary files a/GameServer/assets/images/ui/placeholder.png and b/GameServer/assets/images/ui/placeholder.png differ
diff --git a/GameServer/assets/images/weapons/laser_pistol.png b/GameServer/assets/images/weapons/laser_pistol.png
deleted file mode 100644
index da34474..0000000
Binary files a/GameServer/assets/images/weapons/laser_pistol.png and /dev/null differ
diff --git a/GameServer/assets/images/weapons/laser_sniper_rifle.png b/GameServer/assets/images/weapons/laser_sniper_rifle.png
deleted file mode 100644
index 05dde27..0000000
Binary files a/GameServer/assets/images/weapons/laser_sniper_rifle.png and /dev/null differ
diff --git a/GameServer/assets/images/weapons/starter_blaster.png b/GameServer/assets/images/weapons/starter_blaster.png
deleted file mode 100644
index 2474fde..0000000
Binary files a/GameServer/assets/images/weapons/starter_blaster.png and /dev/null differ
diff --git a/GameServer/data/gso/alliance/research_tree.json b/GameServer/data/gso/alliance/research_tree.json
new file mode 100644
index 0000000..e1f5e5b
--- /dev/null
+++ b/GameServer/data/gso/alliance/research_tree.json
@@ -0,0 +1,28 @@
+{
+ "version": "1.0",
+ "tiers": [
+ {
+ "tier": 1,
+ "techs": [
+ { "id": "alliance_storage_1", "name": "Expanded Warehouse I", "desc": "Increase alliance warehouse cap by 10,000 per resource.", "cost": {"credits":5000,"metal":2000}, "effect": {"warehouseCap":10000}, "prereq": [], "icon": "fa-warehouse", "maxLevel": 3 },
+ { "id": "alliance_xp_1", "name": "Shared Knowledge I", "desc": "+5% XP for all members.", "cost": {"credits":8000,"crystal":500}, "effect": {"memberXpBonus":0.05}, "prereq": [], "icon": "fa-graduation-cap", "maxLevel": 3 },
+ { "id": "alliance_credits_1", "name": "Trade Network I", "desc": "Reduce market listing fee by 0.5% for all members.", "cost": {"credits":6000,"gas":1000}, "effect": {"marketFeeReduction":0.005}, "prereq": [], "icon": "fa-coins", "maxLevel": 2 }
+ ]
+ },
+ {
+ "tier": 2,
+ "techs": [
+ { "id": "alliance_storage_2", "name": "Expanded Warehouse II", "desc": "Increase warehouse cap by an additional 25,000.", "cost": {"credits":15000,"metal":8000}, "effect": {"warehouseCap":25000}, "prereq": ["alliance_storage_1"], "icon": "fa-warehouse", "maxLevel": 1 },
+ { "id": "alliance_craft_1", "name": "Collective Crafting", "desc": "All members gain -10% craft time.", "cost": {"credits":12000,"crystal":1500},"effect": {"craftTimeReduction":0.10}, "prereq": ["alliance_xp_1"], "icon": "fa-hammer", "maxLevel": 2 },
+ { "id": "alliance_defense_1", "name": "Defensive Grid I", "desc": "+10% PvP defense for all members.", "cost": {"credits":10000,"metal":5000}, "effect": {"pvpDefenseBonus":0.10}, "prereq": ["alliance_credits_1"],"icon": "fa-shield-alt", "maxLevel": 3 }
+ ]
+ },
+ {
+ "tier": 3,
+ "techs": [
+ { "id": "alliance_dm_1", "name": "Void Tap", "desc": "+15% dark matter production for all members.", "cost": {"credits":25000,"darkMatter":50},"effect": {"darkMatterBonus":0.15}, "prereq": ["alliance_storage_2","alliance_craft_1"], "icon": "fa-atom", "maxLevel": 1 },
+ { "id": "alliance_fleet_1", "name": "Fleet Coordination", "desc": "+20% fleet mission rewards for all members.", "cost": {"credits":20000,"gas":5000}, "effect": {"fleetRewardBonus":0.20}, "prereq": ["alliance_defense_1"],"icon": "fa-fighter-jet","maxLevel": 2 }
+ ]
+ }
+ ]
+}
diff --git a/GameServer/data/gso/dungeons/dungeons.json b/GameServer/data/gso/dungeons/dungeons.json
deleted file mode 100644
index 1f8e223..0000000
--- a/GameServer/data/gso/dungeons/dungeons.json
+++ /dev/null
@@ -1,97 +0,0 @@
-[
- {
- "id": "pirate_lair",
- "name": "Pirate Lair",
- "description": "Dangerous pirate hideouts with valuable loot",
- "difficulty": "easy",
- "minLevel": 1,
- "maxPlayers": 4,
- "roomCount": [4, 6],
- "energyCost": 15,
- "rewardMultiplier": 1.0,
- "enemyPool": ["space_pirate", "pirate_captain", "defense_turret"],
- "lootTable": [
- { "itemId": "iron_ore", "weight": 40, "qtyMin": 1, "qtyMax": 5 },
- { "itemId": "copper_ore", "weight": 30, "qtyMin": 1, "qtyMax": 3 },
- { "itemId": "bandage", "weight": 20, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "pistol_standard_common", "weight": 10, "qtyMin": 1, "qtyMax": 1 }
- ],
- "ui": { "icon": "fa-skull-crossbones", "color": "#e67e22" }
- },
- {
- "id": "asteroid_mine",
- "name": "Asteroid Mine",
- "description": "Abandoned mining facilities rich in ore deposits",
- "difficulty": "easy",
- "minLevel": 2,
- "maxPlayers": 4,
- "roomCount": [4, 7],
- "energyCost": 10,
- "rewardMultiplier": 0.8,
- "enemyPool": ["mining_drone", "rock_creature", "explosive_asteroid"],
- "lootTable": [
- { "itemId": "iron_ore", "weight": 35, "qtyMin": 2, "qtyMax": 8 },
- { "itemId": "copper_ore", "weight": 30, "qtyMin": 1, "qtyMax": 6 },
- { "itemId": "titanium_ore", "weight": 20, "qtyMin": 1, "qtyMax": 3 },
- { "itemId": "gold_ore", "weight": 15, "qtyMin": 1, "qtyMax": 2 }
- ],
- "ui": { "icon": "fa-meteor", "color": "#95a5a6" }
- },
- {
- "id": "alien_ruins",
- "name": "Alien Ruins",
- "description": "Ancient alien structures filled with mysterious technology",
- "difficulty": "medium",
- "minLevel": 3,
- "maxPlayers": 4,
- "roomCount": [5, 8],
- "energyCost": 20,
- "rewardMultiplier": 1.2,
- "enemyPool": ["alien_guardian", "ancient_drone", "crystal_golem"],
- "lootTable": [
- { "itemId": "flux_crystal", "weight": 30, "qtyMin": 1, "qtyMax": 3 },
- { "itemId": "alien_fauna_sample", "weight": 25, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "basic_circuit", "weight": 25, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "assault_rifle_common", "weight": 20, "qtyMin": 1, "qtyMax": 1 }
- ],
- "ui": { "icon": "fa-monument", "color": "#8e44ad" }
- },
- {
- "id": "corrupted_vault",
- "name": "Corrupted AI Vault",
- "description": "Malfunctioning AI facilities with corrupted security systems",
- "difficulty": "hard",
- "minLevel": 5,
- "maxPlayers": 4,
- "roomCount": [6, 9],
- "energyCost": 25,
- "rewardMultiplier": 1.5,
- "enemyPool": ["security_drone", "corrupted_ai", "virus_program"],
- "lootTable": [
- { "itemId": "logic_circuit", "weight": 30, "qtyMin": 1, "qtyMax": 3 },
- { "itemId": "power_circuit", "weight": 25, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "control_circuit", "weight": 25, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "sniper_rare", "weight": 20, "qtyMin": 1, "qtyMax": 1 }
- ],
- "ui": { "icon": "fa-robot", "color": "#e74c3c" }
- },
- {
- "id": "nebula_anomaly",
- "name": "Nebula Anomaly",
- "description": "Strange energy anomalies in the deep void of space",
- "difficulty": "extreme",
- "minLevel": 8,
- "maxPlayers": 4,
- "roomCount": [7, 10],
- "energyCost": 30,
- "rewardMultiplier": 2.0,
- "enemyPool": ["energy_being", "phase_shifter", "quantum_entity"],
- "lootTable": [
- { "itemId": "quantum_circuit", "weight": 25, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "void_crystal", "weight": 25, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "phase_crystal", "weight": 25, "qtyMin": 1, "qtyMax": 2 },
- { "itemId": "plasma_cutter_epic", "weight": 25, "qtyMin": 1, "qtyMax": 1 }
- ],
- "ui": { "icon": "fa-star", "color": "#2980b9" }
- }
-]
diff --git a/GameServer/data/gso/dungeons/enemies.json b/GameServer/data/gso/dungeons/enemies.json
deleted file mode 100644
index e3795a7..0000000
--- a/GameServer/data/gso/dungeons/enemies.json
+++ /dev/null
@@ -1,15 +0,0 @@
-[
- { "id": "space_pirate", "name": "Space Pirate", "health": 25, "attack": 10, "defense": 3, "speed": 8, "experience": 15, "credits": 12, "rarity": "common" },
- { "id": "pirate_captain", "name": "Pirate Captain", "health": 40, "attack": 15, "defense": 6, "speed": 12, "experience": 30, "credits": 20, "rarity": "uncommon" },
- { "id": "defense_turret", "name": "Defense Turret", "health": 35, "attack": 14, "defense": 8, "speed": 0, "experience": 20, "credits": 15, "rarity": "common" },
- { "id": "mining_drone", "name": "Mining Drone", "health": 20, "attack": 8, "defense": 3, "speed": 5, "experience": 12, "credits": 8, "rarity": "common" },
- { "id": "rock_creature", "name": "Rock Creature", "health": 45, "attack": 6, "defense": 12, "speed": 3, "experience": 18, "credits": 10, "rarity": "common" },
- { "id": "alien_guardian", "name": "Alien Guardian", "health": 50, "attack": 8, "defense": 5, "speed": 6, "experience": 25, "credits": 15, "rarity": "common" },
- { "id": "ancient_drone", "name": "Ancient Drone", "health": 30, "attack": 12, "defense": 2, "speed": 10, "experience": 20, "credits": 10, "rarity": "uncommon" },
- { "id": "crystal_golem", "name": "Crystal Golem", "health": 80, "attack": 6, "defense": 10, "speed": 4, "experience": 35, "credits": 25, "rarity": "rare" },
- { "id": "security_drone", "name": "Security Drone", "health": 35, "attack": 14, "defense": 4, "speed": 10, "experience": 22, "credits": 15, "rarity": "uncommon" },
- { "id": "corrupted_ai", "name": "Corrupted AI", "health": 60, "attack": 20, "defense": 2, "speed": 15, "experience": 40, "credits": 30, "rarity": "rare" },
- { "id": "energy_being", "name": "Energy Being", "health": 55, "attack": 22, "defense": 3, "speed": 18, "experience": 45, "credits": 35, "rarity": "epic" },
- { "id": "phase_shifter", "name": "Phase Shifter", "health": 50, "attack": 25, "defense": 5, "speed": 20, "experience": 50, "credits": 40, "rarity": "epic" },
- { "id": "quantum_entity", "name": "Quantum Entity", "health": 70, "attack": 35, "defense": 5, "speed": 20, "experience": 60, "credits": 50, "rarity": "legendary" }
-]
diff --git a/GameServer/data/gso/items/armour/backpack/backpack_basic_common.json b/GameServer/data/gso/items/armour/backpack/backpack_basic_common.json
deleted file mode 100644
index 915caec..0000000
--- a/GameServer/data/gso/items/armour/backpack/backpack_basic_common.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "backpack_basic_common",
- "texture": "assets/gso/textures/armour/backpack/backpack_basic_common.png",
- "stats": {
- "health": 20,
- "resistance": 0.03,
- "defenceRating": 1,
- "reflectChance": 0.0
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/backpack/backpack_field_rare.json b/GameServer/data/gso/items/armour/backpack/backpack_field_rare.json
deleted file mode 100644
index 36eb7fd..0000000
--- a/GameServer/data/gso/items/armour/backpack/backpack_field_rare.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "backpack_field_rare",
- "texture": "assets/gso/textures/armour/backpack/backpack_field_rare.png",
- "stats": {
- "health": 40,
- "resistance": 0.08,
- "defenceRating": 3,
- "reflectChance": 0.01
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/backpack/backpack_reactor_epic.json b/GameServer/data/gso/items/armour/backpack/backpack_reactor_epic.json
deleted file mode 100644
index 07d86c6..0000000
--- a/GameServer/data/gso/items/armour/backpack/backpack_reactor_epic.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "backpack_reactor_epic",
- "texture": "assets/gso/textures/armour/backpack/backpack_reactor_epic.png",
- "stats": {
- "health": 70,
- "resistance": 0.15,
- "defenceRating": 6,
- "reflectChance": 0.03
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/body/body_basic_common.json b/GameServer/data/gso/items/armour/body/body_basic_common.json
deleted file mode 100644
index 461b4cb..0000000
--- a/GameServer/data/gso/items/armour/body/body_basic_common.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "body_basic_common",
- "texture": "assets/gso/textures/armour/body/body_basic_common.png",
- "stats": {
- "health": 60,
- "resistance": 0.1,
- "defenceRating": 4,
- "reflectChance": 0.0
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/body/body_exosuit_epic.json b/GameServer/data/gso/items/armour/body/body_exosuit_epic.json
deleted file mode 100644
index 7f70a3f..0000000
--- a/GameServer/data/gso/items/armour/body/body_exosuit_epic.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "body_exosuit_epic",
- "texture": "assets/gso/textures/armour/body/body_exosuit_epic.png",
- "stats": {
- "health": 180,
- "resistance": 0.3,
- "defenceRating": 14,
- "reflectChance": 0.05
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/body/body_plated_rare.json b/GameServer/data/gso/items/armour/body/body_plated_rare.json
deleted file mode 100644
index 3d724e8..0000000
--- a/GameServer/data/gso/items/armour/body/body_plated_rare.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "body_plated_rare",
- "texture": "assets/gso/textures/armour/body/body_plated_rare.png",
- "stats": {
- "health": 110,
- "resistance": 0.2,
- "defenceRating": 8,
- "reflectChance": 0.02
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/boots/boots_assault_rare.json b/GameServer/data/gso/items/armour/boots/boots_assault_rare.json
deleted file mode 100644
index a4b641a..0000000
--- a/GameServer/data/gso/items/armour/boots/boots_assault_rare.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "boots_assault_rare",
- "texture": "assets/gso/textures/armour/boots/boots_assault_rare.png",
- "stats": {
- "health": 40,
- "resistance": 0.12,
- "defenceRating": 4,
- "reflectChance": 0.01
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/boots/boots_basic_common.json b/GameServer/data/gso/items/armour/boots/boots_basic_common.json
deleted file mode 100644
index 110c2a5..0000000
--- a/GameServer/data/gso/items/armour/boots/boots_basic_common.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "boots_basic_common",
- "texture": "assets/gso/textures/armour/boots/boots_basic_common.png",
- "stats": {
- "health": 20,
- "resistance": 0.05,
- "defenceRating": 2,
- "reflectChance": 0.0
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/boots/boots_gravity_epic.json b/GameServer/data/gso/items/armour/boots/boots_gravity_epic.json
deleted file mode 100644
index ea5a086..0000000
--- a/GameServer/data/gso/items/armour/boots/boots_gravity_epic.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "boots_gravity_epic",
- "texture": "assets/gso/textures/armour/boots/boots_gravity_epic.png",
- "stats": {
- "health": 65,
- "resistance": 0.2,
- "defenceRating": 7,
- "reflectChance": 0.025
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/hands/hands_basic_common.json b/GameServer/data/gso/items/armour/hands/hands_basic_common.json
deleted file mode 100644
index bbf01e6..0000000
--- a/GameServer/data/gso/items/armour/hands/hands_basic_common.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "hands_basic_common",
- "texture": "assets/gso/textures/armour/hands/hands_basic_common.png",
- "stats": {
- "health": 15,
- "resistance": 0.04,
- "defenceRating": 1,
- "reflectChance": 0.0
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/hands/hands_combat_rare.json b/GameServer/data/gso/items/armour/hands/hands_combat_rare.json
deleted file mode 100644
index 4b698e2..0000000
--- a/GameServer/data/gso/items/armour/hands/hands_combat_rare.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "hands_combat_rare",
- "texture": "assets/gso/textures/armour/hands/hands_combat_rare.png",
- "stats": {
- "health": 30,
- "resistance": 0.1,
- "defenceRating": 3,
- "reflectChance": 0.01
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/hands/hands_elite_epic.json b/GameServer/data/gso/items/armour/hands/hands_elite_epic.json
deleted file mode 100644
index 69a6ba1..0000000
--- a/GameServer/data/gso/items/armour/hands/hands_elite_epic.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "hands_elite_epic",
- "texture": "assets/gso/textures/armour/hands/hands_elite_epic.png",
- "stats": {
- "health": 50,
- "resistance": 0.18,
- "defenceRating": 6,
- "reflectChance": 0.025
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/helmet/helmet_basic_common.json b/GameServer/data/gso/items/armour/helmet/helmet_basic_common.json
deleted file mode 100644
index 88ea0a0..0000000
--- a/GameServer/data/gso/items/armour/helmet/helmet_basic_common.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "helmet_basic_common",
- "texture": "assets/gso/textures/armour/helmet/helmet_basic_common.png",
- "stats": {
- "health": 25,
- "resistance": 0.05,
- "defenceRating": 2,
- "reflectChance": 0.0
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/helmet/helmet_reinforced_rare.json b/GameServer/data/gso/items/armour/helmet/helmet_reinforced_rare.json
deleted file mode 100644
index 557fb37..0000000
--- a/GameServer/data/gso/items/armour/helmet/helmet_reinforced_rare.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "helmet_reinforced_rare",
- "texture": "assets/gso/textures/armour/helmet/helmet_reinforced_rare.png",
- "stats": {
- "health": 45,
- "resistance": 0.12,
- "defenceRating": 5,
- "reflectChance": 0.01
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/helmet/helmet_tactical_epic.json b/GameServer/data/gso/items/armour/helmet/helmet_tactical_epic.json
deleted file mode 100644
index 46d37de..0000000
--- a/GameServer/data/gso/items/armour/helmet/helmet_tactical_epic.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "helmet_tactical_epic",
- "texture": "assets/gso/textures/armour/helmet/helmet_tactical_epic.png",
- "stats": {
- "health": 70,
- "resistance": 0.2,
- "defenceRating": 8,
- "reflectChance": 0.03
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/pants/pants_basic_common.json b/GameServer/data/gso/items/armour/pants/pants_basic_common.json
deleted file mode 100644
index 87e7248..0000000
--- a/GameServer/data/gso/items/armour/pants/pants_basic_common.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "pants_basic_common",
- "texture": "assets/gso/textures/armour/pants/pants_basic_common.png",
- "stats": {
- "health": 30,
- "resistance": 0.06,
- "defenceRating": 2,
- "reflectChance": 0.0
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/pants/pants_exo_epic.json b/GameServer/data/gso/items/armour/pants/pants_exo_epic.json
deleted file mode 100644
index 3cdba58..0000000
--- a/GameServer/data/gso/items/armour/pants/pants_exo_epic.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "pants_exo_epic",
- "texture": "assets/gso/textures/armour/pants/pants_exo_epic.png",
- "stats": {
- "health": 85,
- "resistance": 0.22,
- "defenceRating": 9,
- "reflectChance": 0.03
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armour/pants/pants_reinforced_rare.json b/GameServer/data/gso/items/armour/pants/pants_reinforced_rare.json
deleted file mode 100644
index 6710535..0000000
--- a/GameServer/data/gso/items/armour/pants/pants_reinforced_rare.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "templates": {
- "armour": {
- "id": "pants_reinforced_rare",
- "texture": "assets/gso/textures/armour/pants/pants_reinforced_rare.png",
- "stats": {
- "health": 55,
- "resistance": 0.14,
- "defenceRating": 5,
- "reflectChance": 0.015
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/backpack_field_rare.json b/GameServer/data/gso/items/armours/backpack_field_rare.json
new file mode 100644
index 0000000..be4eaaf
--- /dev/null
+++ b/GameServer/data/gso/items/armours/backpack_field_rare.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "backpack_field_rare",
+ "texture": "assets/gso/textures/armour/backpack/backpack_field_rare.png",
+ "stats": {
+ "health": 40,
+ "resistance": 0.08,
+ "defenceRating": 3,
+ "reflectChance": 0.01
+ },
+ "name": "Backpack Field Rare",
+ "type": "armour",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Backpack Field Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/backpack_reactor_epic.json b/GameServer/data/gso/items/armours/backpack_reactor_epic.json
new file mode 100644
index 0000000..5137c07
--- /dev/null
+++ b/GameServer/data/gso/items/armours/backpack_reactor_epic.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "backpack_reactor_epic",
+ "texture": "assets/gso/textures/armour/backpack/backpack_reactor_epic.png",
+ "stats": {
+ "health": 70,
+ "resistance": 0.15,
+ "defenceRating": 6,
+ "reflectChance": 0.03
+ },
+ "name": "Backpack Reactor Epic",
+ "type": "armour",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Backpack Reactor Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/boots_assault_rare.json b/GameServer/data/gso/items/armours/boots_assault_rare.json
new file mode 100644
index 0000000..10a3343
--- /dev/null
+++ b/GameServer/data/gso/items/armours/boots_assault_rare.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "boots_assault_rare",
+ "texture": "assets/gso/textures/armour/boots/boots_assault_rare.png",
+ "stats": {
+ "health": 40,
+ "resistance": 0.12,
+ "defenceRating": 4,
+ "reflectChance": 0.01
+ },
+ "name": "Boots Assault Rare",
+ "type": "armour",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Boots Assault Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/boots_gravity_epic.json b/GameServer/data/gso/items/armours/boots_gravity_epic.json
new file mode 100644
index 0000000..aa5cf81
--- /dev/null
+++ b/GameServer/data/gso/items/armours/boots_gravity_epic.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "boots_gravity_epic",
+ "texture": "assets/gso/textures/armour/boots/boots_gravity_epic.png",
+ "stats": {
+ "health": 65,
+ "resistance": 0.2,
+ "defenceRating": 7,
+ "reflectChance": 0.025
+ },
+ "name": "Boots Gravity Epic",
+ "type": "armour",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Boots Gravity Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/hands_basic_common.json b/GameServer/data/gso/items/armours/hands_basic_common.json
new file mode 100644
index 0000000..9d180ba
--- /dev/null
+++ b/GameServer/data/gso/items/armours/hands_basic_common.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "hands_basic_common",
+ "texture": "assets/gso/textures/armour/hands/hands_basic_common.png",
+ "stats": {
+ "health": 15,
+ "resistance": 0.04,
+ "defenceRating": 1,
+ "reflectChance": 0.0
+ },
+ "name": "Hands Basic Common",
+ "type": "armour",
+ "rarity": "common",
+ "price": 1000,
+ "currency": "credits",
+ "description": "Hands Basic Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 1
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/hands_combat_rare.json b/GameServer/data/gso/items/armours/hands_combat_rare.json
new file mode 100644
index 0000000..9c4261c
--- /dev/null
+++ b/GameServer/data/gso/items/armours/hands_combat_rare.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "hands_combat_rare",
+ "texture": "assets/gso/textures/armour/hands/hands_combat_rare.png",
+ "stats": {
+ "health": 30,
+ "resistance": 0.1,
+ "defenceRating": 3,
+ "reflectChance": 0.01
+ },
+ "name": "Hands Combat Rare",
+ "type": "armour",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Hands Combat Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/hands_elite_epic.json b/GameServer/data/gso/items/armours/hands_elite_epic.json
new file mode 100644
index 0000000..4406aea
--- /dev/null
+++ b/GameServer/data/gso/items/armours/hands_elite_epic.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "hands_elite_epic",
+ "texture": "assets/gso/textures/armour/hands/hands_elite_epic.png",
+ "stats": {
+ "health": 50,
+ "resistance": 0.18,
+ "defenceRating": 6,
+ "reflectChance": 0.025
+ },
+ "name": "Hands Elite Epic",
+ "type": "armour",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Hands Elite Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/helmet_tactical_epic.json b/GameServer/data/gso/items/armours/helmet_tactical_epic.json
new file mode 100644
index 0000000..5ab8d02
--- /dev/null
+++ b/GameServer/data/gso/items/armours/helmet_tactical_epic.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "helmet_tactical_epic",
+ "texture": "assets/gso/textures/armour/helmet/helmet_tactical_epic.png",
+ "stats": {
+ "health": 70,
+ "resistance": 0.2,
+ "defenceRating": 8,
+ "reflectChance": 0.03
+ },
+ "name": "Helmet Tactical Epic",
+ "type": "armour",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Helmet Tactical Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/pants_exo_epic.json b/GameServer/data/gso/items/armours/pants_exo_epic.json
new file mode 100644
index 0000000..d6dc39f
--- /dev/null
+++ b/GameServer/data/gso/items/armours/pants_exo_epic.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "pants_exo_epic",
+ "texture": "assets/gso/textures/armour/pants/pants_exo_epic.png",
+ "stats": {
+ "health": 85,
+ "resistance": 0.22,
+ "defenceRating": 9,
+ "reflectChance": 0.03
+ },
+ "name": "Pants Exo Epic",
+ "type": "armour",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Pants Exo Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/armours/pants_reinforced_rare.json b/GameServer/data/gso/items/armours/pants_reinforced_rare.json
new file mode 100644
index 0000000..f3b862c
--- /dev/null
+++ b/GameServer/data/gso/items/armours/pants_reinforced_rare.json
@@ -0,0 +1,28 @@
+{
+ "templates": {
+ "armour": {
+ "id": "pants_reinforced_rare",
+ "texture": "assets/gso/textures/armour/pants/pants_reinforced_rare.png",
+ "stats": {
+ "health": 55,
+ "resistance": 0.14,
+ "defenceRating": 5,
+ "reflectChance": 0.015
+ },
+ "name": "Pants Reinforced Rare",
+ "type": "armour",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Pants Reinforced Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/hullPlating/misc/ballistic_alloy_common.json b/GameServer/data/gso/items/hullPlating/misc/ballistic_alloy_common.json
index d646b25..40dfd62 100644
--- a/GameServer/data/gso/items/hullPlating/misc/ballistic_alloy_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/ballistic_alloy_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Ballistic Alloy Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Ballistic Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/carbon_titanium_composite_common.json b/GameServer/data/gso/items/hullPlating/misc/carbon_titanium_composite_common.json
index 238220e..4be43e6 100644
--- a/GameServer/data/gso/items/hullPlating/misc/carbon_titanium_composite_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/carbon_titanium_composite_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Carbon Titanium Composite Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Carbon Titanium Composite Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/chrono_alloy_common.json b/GameServer/data/gso/items/hullPlating/misc/chrono_alloy_common.json
index c24c500..a6c73a4 100644
--- a/GameServer/data/gso/items/hullPlating/misc/chrono_alloy_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/chrono_alloy_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Chrono Alloy Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Chrono Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/dimensional_alloy_common.json b/GameServer/data/gso/items/hullPlating/misc/dimensional_alloy_common.json
index bd6d924..721747d 100644
--- a/GameServer/data/gso/items/hullPlating/misc/dimensional_alloy_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/dimensional_alloy_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Dimensional Alloy Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Dimensional Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/flux_core_alloy_common.json b/GameServer/data/gso/items/hullPlating/misc/flux_core_alloy_common.json
index 79c38ac..63b2f4f 100644
--- a/GameServer/data/gso/items/hullPlating/misc/flux_core_alloy_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/flux_core_alloy_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Flux Core Alloy Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Flux Core Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/neutronium_composite_common.json b/GameServer/data/gso/items/hullPlating/misc/neutronium_composite_common.json
index 5ee776e..1ac9ab5 100644
--- a/GameServer/data/gso/items/hullPlating/misc/neutronium_composite_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/neutronium_composite_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Neutronium Composite Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Neutronium Composite Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/phase_alloy_common.json b/GameServer/data/gso/items/hullPlating/misc/phase_alloy_common.json
index e598e36..111f587 100644
--- a/GameServer/data/gso/items/hullPlating/misc/phase_alloy_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/phase_alloy_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Phase Alloy Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Phase Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/plasma_channel_alloy_common.json b/GameServer/data/gso/items/hullPlating/misc/plasma_channel_alloy_common.json
index 9e6a70f..a68c0ac 100644
--- a/GameServer/data/gso/items/hullPlating/misc/plasma_channel_alloy_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/plasma_channel_alloy_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Plasma Channel Alloy Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Plasma Channel Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/reinforced_steel_common.json b/GameServer/data/gso/items/hullPlating/misc/reinforced_steel_common.json
index f987a2c..1b92a59 100644
--- a/GameServer/data/gso/items/hullPlating/misc/reinforced_steel_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/reinforced_steel_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Reinforced Steel Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Reinforced Steel Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/superconductive_alloy_common.json b/GameServer/data/gso/items/hullPlating/misc/superconductive_alloy_common.json
index b6f44cb..e815e1a 100644
--- a/GameServer/data/gso/items/hullPlating/misc/superconductive_alloy_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/superconductive_alloy_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Superconductive Alloy Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Superconductive Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/misc/voidsteel_common.json b/GameServer/data/gso/items/hullPlating/misc/voidsteel_common.json
index 27bbd6d..78d187f 100644
--- a/GameServer/data/gso/items/hullPlating/misc/voidsteel_common.json
+++ b/GameServer/data/gso/items/hullPlating/misc/voidsteel_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Voidsteel Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Voidsteel Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/plating/ablative_plating_common.json b/GameServer/data/gso/items/hullPlating/plating/ablative_plating_common.json
index 096cc7c..afd6c0a 100644
--- a/GameServer/data/gso/items/hullPlating/plating/ablative_plating_common.json
+++ b/GameServer/data/gso/items/hullPlating/plating/ablative_plating_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Ablative Plating Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Ablative Plating Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/section/advanced_hull_section_common.json b/GameServer/data/gso/items/hullPlating/section/advanced_hull_section_common.json
index d83b4c0..aecd233 100644
--- a/GameServer/data/gso/items/hullPlating/section/advanced_hull_section_common.json
+++ b/GameServer/data/gso/items/hullPlating/section/advanced_hull_section_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Advanced Hull Section Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Advanced Hull Section Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/section/armor_hull_section_common.json b/GameServer/data/gso/items/hullPlating/section/armor_hull_section_common.json
index 06f0106..f40f371 100644
--- a/GameServer/data/gso/items/hullPlating/section/armor_hull_section_common.json
+++ b/GameServer/data/gso/items/hullPlating/section/armor_hull_section_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Armor Hull Section Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Armor Hull Section Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/section/exotic_hull_section_common.json b/GameServer/data/gso/items/hullPlating/section/exotic_hull_section_common.json
index 40f22f6..c7fe803 100644
--- a/GameServer/data/gso/items/hullPlating/section/exotic_hull_section_common.json
+++ b/GameServer/data/gso/items/hullPlating/section/exotic_hull_section_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Exotic Hull Section Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Exotic Hull Section Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/section/heavy_hull_section_common.json b/GameServer/data/gso/items/hullPlating/section/heavy_hull_section_common.json
index 9be3680..af8f70f 100644
--- a/GameServer/data/gso/items/hullPlating/section/heavy_hull_section_common.json
+++ b/GameServer/data/gso/items/hullPlating/section/heavy_hull_section_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Heavy Hull Section Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Heavy Hull Section Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/section/light_hull_section_common.json b/GameServer/data/gso/items/hullPlating/section/light_hull_section_common.json
index 72d22a2..83776ae 100644
--- a/GameServer/data/gso/items/hullPlating/section/light_hull_section_common.json
+++ b/GameServer/data/gso/items/hullPlating/section/light_hull_section_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Light Hull Section Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Light Hull Section Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/hullPlating/section/standard_hull_section_common.json b/GameServer/data/gso/items/hullPlating/section/standard_hull_section_common.json
index 731d0a8..411c45b 100644
--- a/GameServer/data/gso/items/hullPlating/section/standard_hull_section_common.json
+++ b/GameServer/data/gso/items/hullPlating/section/standard_hull_section_common.json
@@ -8,6 +8,20 @@
"resistance": 0.0,
"defenceRating": 0,
"reflectChance": 0.0
+ },
+ "name": "Standard Hull Section Common",
+ "type": "hullPlating",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Standard Hull Section Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/bio/bio_pulp.json b/GameServer/data/gso/items/materials/bio/bio_pulp.json
index 9694a7d..cad173e 100644
--- a/GameServer/data/gso/items/materials/bio/bio_pulp.json
+++ b/GameServer/data/gso/items/materials/bio/bio_pulp.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "bio"
+ },
+ "name": "Bio Pulp Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Bio Pulp Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/bio/organic_insulation.json b/GameServer/data/gso/items/materials/bio/organic_insulation.json
index 77b72e7..06e751a 100644
--- a/GameServer/data/gso/items/materials/bio/organic_insulation.json
+++ b/GameServer/data/gso/items/materials/bio/organic_insulation.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "bio"
+ },
+ "name": "Organic Insulation Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Organic Insulation Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/bio/plant_matter.json b/GameServer/data/gso/items/materials/bio/plant_matter.json
index 901dafd..8724da8 100644
--- a/GameServer/data/gso/items/materials/bio/plant_matter.json
+++ b/GameServer/data/gso/items/materials/bio/plant_matter.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "bio"
+ },
+ "name": "Plant Matter Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Plant Matter Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/aluminum_alloy.json b/GameServer/data/gso/items/materials/chemical/aluminum_alloy.json
index 3a475d7..27ace2d 100644
--- a/GameServer/data/gso/items/materials/chemical/aluminum_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/aluminum_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Aluminum Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Aluminum Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/bio_composite_material.json b/GameServer/data/gso/items/materials/chemical/bio_composite_material.json
index f7f90da..204401b 100644
--- a/GameServer/data/gso/items/materials/chemical/bio_composite_material.json
+++ b/GameServer/data/gso/items/materials/chemical/bio_composite_material.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Bio Composite Material Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Bio Composite Material Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/carbon_nanotube_alloy.json b/GameServer/data/gso/items/materials/chemical/carbon_nanotube_alloy.json
index 70cb067..f8e50dc 100644
--- a/GameServer/data/gso/items/materials/chemical/carbon_nanotube_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/carbon_nanotube_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Carbon Nanotube Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Carbon Nanotube Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/ceramic_composite.json b/GameServer/data/gso/items/materials/chemical/ceramic_composite.json
index ef39f66..3f8d7d5 100644
--- a/GameServer/data/gso/items/materials/chemical/ceramic_composite.json
+++ b/GameServer/data/gso/items/materials/chemical/ceramic_composite.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Ceramic Composite Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Ceramic Composite Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/explosive_compound.json b/GameServer/data/gso/items/materials/chemical/explosive_compound.json
index dfd4c0c..1d10325 100644
--- a/GameServer/data/gso/items/materials/chemical/explosive_compound.json
+++ b/GameServer/data/gso/items/materials/chemical/explosive_compound.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Explosive Compound Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Explosive Compound Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/flex_alloy.json b/GameServer/data/gso/items/materials/chemical/flex_alloy.json
index 84ba999..16252ed 100644
--- a/GameServer/data/gso/items/materials/chemical/flex_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/flex_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Flex Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Flex Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/fusion_rated_alloy.json b/GameServer/data/gso/items/materials/chemical/fusion_rated_alloy.json
index 6a1c270..ff90e38 100644
--- a/GameServer/data/gso/items/materials/chemical/fusion_rated_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/fusion_rated_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Fusion Rated Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Fusion Rated Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/glass_composite.json b/GameServer/data/gso/items/materials/chemical/glass_composite.json
index 71ec3dc..144b81d 100644
--- a/GameServer/data/gso/items/materials/chemical/glass_composite.json
+++ b/GameServer/data/gso/items/materials/chemical/glass_composite.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Glass Composite Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Glass Composite Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/radiation_shield_alloy.json b/GameServer/data/gso/items/materials/chemical/radiation_shield_alloy.json
index 2cfea79..47a1ee5 100644
--- a/GameServer/data/gso/items/materials/chemical/radiation_shield_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/radiation_shield_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Radiation Shield Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Radiation Shield Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/reactive_armor_alloy.json b/GameServer/data/gso/items/materials/chemical/reactive_armor_alloy.json
index 93ac7fe..83ced08 100644
--- a/GameServer/data/gso/items/materials/chemical/reactive_armor_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/reactive_armor_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Reactive Armor Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Reactive Armor Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/resin.json b/GameServer/data/gso/items/materials/chemical/resin.json
index 97e5611..744981a 100644
--- a/GameServer/data/gso/items/materials/chemical/resin.json
+++ b/GameServer/data/gso/items/materials/chemical/resin.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Resin Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Resin Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/rubber_polymer.json b/GameServer/data/gso/items/materials/chemical/rubber_polymer.json
index 577cc78..56257dd 100644
--- a/GameServer/data/gso/items/materials/chemical/rubber_polymer.json
+++ b/GameServer/data/gso/items/materials/chemical/rubber_polymer.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Rubber Polymer Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Rubber Polymer Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/servo_alloy.json b/GameServer/data/gso/items/materials/chemical/servo_alloy.json
index 2d20cd4..05f5838 100644
--- a/GameServer/data/gso/items/materials/chemical/servo_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/servo_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Servo Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Servo Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/steel_alloy.json b/GameServer/data/gso/items/materials/chemical/steel_alloy.json
index 84b7c43..2f56105 100644
--- a/GameServer/data/gso/items/materials/chemical/steel_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/steel_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Steel Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Steel Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/titanium_alloy.json b/GameServer/data/gso/items/materials/chemical/titanium_alloy.json
index 3ef1d08..93f69df 100644
--- a/GameServer/data/gso/items/materials/chemical/titanium_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/titanium_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Titanium Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Titanium Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/transparent_alloy.json b/GameServer/data/gso/items/materials/chemical/transparent_alloy.json
index 888adba..3466de6 100644
--- a/GameServer/data/gso/items/materials/chemical/transparent_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/transparent_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Transparent Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Transparent Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/chemical/tungsten_alloy.json b/GameServer/data/gso/items/materials/chemical/tungsten_alloy.json
index 1ff843a..082b928 100644
--- a/GameServer/data/gso/items/materials/chemical/tungsten_alloy.json
+++ b/GameServer/data/gso/items/materials/chemical/tungsten_alloy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "chemical"
+ },
+ "name": "Tungsten Alloy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Tungsten Alloy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/ai_core_circuit.json b/GameServer/data/gso/items/materials/electronics/ai_core_circuit.json
index 3aaa251..af43459 100644
--- a/GameServer/data/gso/items/materials/electronics/ai_core_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/ai_core_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Ai Core Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Ai Core Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/basic_circuit.json b/GameServer/data/gso/items/materials/electronics/basic_circuit.json
index 785c0a7..9900667 100644
--- a/GameServer/data/gso/items/materials/electronics/basic_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/basic_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Basic Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Basic Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/control_circuit.json b/GameServer/data/gso/items/materials/electronics/control_circuit.json
index 65d1d4a..62b3e58 100644
--- a/GameServer/data/gso/items/materials/electronics/control_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/control_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Control Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Control Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/dimensional_logic_circuit.json b/GameServer/data/gso/items/materials/electronics/dimensional_logic_circuit.json
index 126c3fc..890cf9d 100644
--- a/GameServer/data/gso/items/materials/electronics/dimensional_logic_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/dimensional_logic_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Dimensional Logic Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Dimensional Logic Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/high_density_circuit.json b/GameServer/data/gso/items/materials/electronics/high_density_circuit.json
index 6aa4e33..576788f 100644
--- a/GameServer/data/gso/items/materials/electronics/high_density_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/high_density_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "High Density Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "High Density Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/logic_circuit.json b/GameServer/data/gso/items/materials/electronics/logic_circuit.json
index 47a1720..2cccdeb 100644
--- a/GameServer/data/gso/items/materials/electronics/logic_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/logic_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Logic Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Logic Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/navigation_circuit.json b/GameServer/data/gso/items/materials/electronics/navigation_circuit.json
index 92b938d..35207e2 100644
--- a/GameServer/data/gso/items/materials/electronics/navigation_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/navigation_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Navigation Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Navigation Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/power_circuit.json b/GameServer/data/gso/items/materials/electronics/power_circuit.json
index 88b7ad2..831766a 100644
--- a/GameServer/data/gso/items/materials/electronics/power_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/power_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Power Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Power Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/processor_circuit.json b/GameServer/data/gso/items/materials/electronics/processor_circuit.json
index 155c515..a310449 100644
--- a/GameServer/data/gso/items/materials/electronics/processor_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/processor_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Processor Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Processor Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/quantum_circuit.json b/GameServer/data/gso/items/materials/electronics/quantum_circuit.json
index c5c7fa9..b53e094 100644
--- a/GameServer/data/gso/items/materials/electronics/quantum_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/quantum_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Quantum Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Quantum Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/reactor_control_circuit.json b/GameServer/data/gso/items/materials/electronics/reactor_control_circuit.json
index 4087bde..5a52d97 100644
--- a/GameServer/data/gso/items/materials/electronics/reactor_control_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/reactor_control_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Reactor Control Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Reactor Control Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/sensor_array_circuit.json b/GameServer/data/gso/items/materials/electronics/sensor_array_circuit.json
index e07e563..69f5fb1 100644
--- a/GameServer/data/gso/items/materials/electronics/sensor_array_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/sensor_array_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Sensor Array Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Sensor Array Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/sentient_core_circuit.json b/GameServer/data/gso/items/materials/electronics/sentient_core_circuit.json
index 0db17ab..c98a6a4 100644
--- a/GameServer/data/gso/items/materials/electronics/sentient_core_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/sentient_core_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Sentient Core Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Sentient Core Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/shield_control_circuit.json b/GameServer/data/gso/items/materials/electronics/shield_control_circuit.json
index e1dd4b1..1e8d7a1 100644
--- a/GameServer/data/gso/items/materials/electronics/shield_control_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/shield_control_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Shield Control Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Shield Control Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/stealth_circuit.json b/GameServer/data/gso/items/materials/electronics/stealth_circuit.json
index 3345f32..35e2101 100644
--- a/GameServer/data/gso/items/materials/electronics/stealth_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/stealth_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Stealth Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Stealth Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/warp_navigation_circuit.json b/GameServer/data/gso/items/materials/electronics/warp_navigation_circuit.json
index ee3be9b..1699cfc 100644
--- a/GameServer/data/gso/items/materials/electronics/warp_navigation_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/warp_navigation_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Warp Navigation Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Warp Navigation Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/electronics/weapon_control_circuit.json b/GameServer/data/gso/items/materials/electronics/weapon_control_circuit.json
index c0b8707..7beda37 100644
--- a/GameServer/data/gso/items/materials/electronics/weapon_control_circuit.json
+++ b/GameServer/data/gso/items/materials/electronics/weapon_control_circuit.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "electronics"
+ },
+ "name": "Weapon Control Circuit Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Weapon Control Circuit Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/fabric/plant_cloth.json b/GameServer/data/gso/items/materials/fabric/plant_cloth.json
index 5f8be11..deda453 100644
--- a/GameServer/data/gso/items/materials/fabric/plant_cloth.json
+++ b/GameServer/data/gso/items/materials/fabric/plant_cloth.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "fabric"
+ },
+ "name": "Plant Cloth Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Plant Cloth Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/fabric/plant_fiber.json b/GameServer/data/gso/items/materials/fabric/plant_fiber.json
index 2b3b757..1d2aa02 100644
--- a/GameServer/data/gso/items/materials/fabric/plant_fiber.json
+++ b/GameServer/data/gso/items/materials/fabric/plant_fiber.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "fabric"
+ },
+ "name": "Plant Fiber Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Plant Fiber Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/bread.json b/GameServer/data/gso/items/materials/food/bread.json
index d53913a..bcc1528 100644
--- a/GameServer/data/gso/items/materials/food/bread.json
+++ b/GameServer/data/gso/items/materials/food/bread.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Bread Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Bread Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/fish.json b/GameServer/data/gso/items/materials/food/fish.json
index de1c1dd..13bbac3 100644
--- a/GameServer/data/gso/items/materials/food/fish.json
+++ b/GameServer/data/gso/items/materials/food/fish.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Fish Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Fish Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/fish_meat.json b/GameServer/data/gso/items/materials/food/fish_meat.json
index cbbca71..2e92960 100644
--- a/GameServer/data/gso/items/materials/food/fish_meat.json
+++ b/GameServer/data/gso/items/materials/food/fish_meat.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Fish Meat Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Fish Meat Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/flour.json b/GameServer/data/gso/items/materials/food/flour.json
index 51214b6..4ddb70d 100644
--- a/GameServer/data/gso/items/materials/food/flour.json
+++ b/GameServer/data/gso/items/materials/food/flour.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Flour Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Flour Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/fruit_plant.json b/GameServer/data/gso/items/materials/food/fruit_plant.json
index 2dd83c4..6a21e6b 100644
--- a/GameServer/data/gso/items/materials/food/fruit_plant.json
+++ b/GameServer/data/gso/items/materials/food/fruit_plant.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Fruit Plant Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Fruit Plant Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/grain.json b/GameServer/data/gso/items/materials/food/grain.json
index 7c217eb..39624f5 100644
--- a/GameServer/data/gso/items/materials/food/grain.json
+++ b/GameServer/data/gso/items/materials/food/grain.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Grain Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Grain Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/grain_crop.json b/GameServer/data/gso/items/materials/food/grain_crop.json
index 4d94bf6..345b507 100644
--- a/GameServer/data/gso/items/materials/food/grain_crop.json
+++ b/GameServer/data/gso/items/materials/food/grain_crop.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Grain Crop Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Grain Crop Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/meat_stew.json b/GameServer/data/gso/items/materials/food/meat_stew.json
index 7708a18..88f1395 100644
--- a/GameServer/data/gso/items/materials/food/meat_stew.json
+++ b/GameServer/data/gso/items/materials/food/meat_stew.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Meat Stew Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Meat Stew Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/ration_pack.json b/GameServer/data/gso/items/materials/food/ration_pack.json
index 080b4cd..d60709c 100644
--- a/GameServer/data/gso/items/materials/food/ration_pack.json
+++ b/GameServer/data/gso/items/materials/food/ration_pack.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Ration Pack Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Ration Pack Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/vegetable_plant.json b/GameServer/data/gso/items/materials/food/vegetable_plant.json
index 617b2cc..2192332 100644
--- a/GameServer/data/gso/items/materials/food/vegetable_plant.json
+++ b/GameServer/data/gso/items/materials/food/vegetable_plant.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Vegetable Plant Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Vegetable Plant Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/food/vegetable_stew.json b/GameServer/data/gso/items/materials/food/vegetable_stew.json
index d701e38..3223791 100644
--- a/GameServer/data/gso/items/materials/food/vegetable_stew.json
+++ b/GameServer/data/gso/items/materials/food/vegetable_stew.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "food"
+ },
+ "name": "Vegetable Stew Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Vegetable Stew Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/aluminum_ingot.json b/GameServer/data/gso/items/materials/ingot/aluminum_ingot.json
index ce236e0..eb9693e 100644
--- a/GameServer/data/gso/items/materials/ingot/aluminum_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/aluminum_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Aluminum Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Aluminum Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/carbon_ingot.json b/GameServer/data/gso/items/materials/ingot/carbon_ingot.json
index e4b6c3b..a512624 100644
--- a/GameServer/data/gso/items/materials/ingot/carbon_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/carbon_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Carbon Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Carbon Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/chromium_ingot.json b/GameServer/data/gso/items/materials/ingot/chromium_ingot.json
index 8d7e546..4856922 100644
--- a/GameServer/data/gso/items/materials/ingot/chromium_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/chromium_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Chromium Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Chromium Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/chronium_ingot.json b/GameServer/data/gso/items/materials/ingot/chronium_ingot.json
index cdcf576..a439bbb 100644
--- a/GameServer/data/gso/items/materials/ingot/chronium_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/chronium_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Chronium Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Chronium Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/copper_ingot.json b/GameServer/data/gso/items/materials/ingot/copper_ingot.json
index e138c02..99dc765 100644
--- a/GameServer/data/gso/items/materials/ingot/copper_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/copper_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Copper Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Copper Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/darksteel_ingot.json b/GameServer/data/gso/items/materials/ingot/darksteel_ingot.json
index 7f1f87f..2ff87d5 100644
--- a/GameServer/data/gso/items/materials/ingot/darksteel_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/darksteel_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Darksteel Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Darksteel Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/gold_ingot.json b/GameServer/data/gso/items/materials/ingot/gold_ingot.json
index 5daff67..97fb150 100644
--- a/GameServer/data/gso/items/materials/ingot/gold_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/gold_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Gold Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Gold Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/iron_ingot.json b/GameServer/data/gso/items/materials/ingot/iron_ingot.json
index fc720b8..bbb4886 100644
--- a/GameServer/data/gso/items/materials/ingot/iron_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/iron_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Iron Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Iron Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/magnesium_ingot.json b/GameServer/data/gso/items/materials/ingot/magnesium_ingot.json
index 2aa68f8..5423985 100644
--- a/GameServer/data/gso/items/materials/ingot/magnesium_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/magnesium_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Magnesium Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Magnesium Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/neutronium_ingot.json b/GameServer/data/gso/items/materials/ingot/neutronium_ingot.json
index c41551b..f98a4fc 100644
--- a/GameServer/data/gso/items/materials/ingot/neutronium_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/neutronium_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Neutronium Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Neutronium Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/platinum_ingot.json b/GameServer/data/gso/items/materials/ingot/platinum_ingot.json
index f0facc6..3c40c00 100644
--- a/GameServer/data/gso/items/materials/ingot/platinum_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/platinum_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Platinum Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Platinum Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/silver_ingot.json b/GameServer/data/gso/items/materials/ingot/silver_ingot.json
index c1bf929..4399bdb 100644
--- a/GameServer/data/gso/items/materials/ingot/silver_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/silver_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Silver Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Silver Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/titanium_ingot.json b/GameServer/data/gso/items/materials/ingot/titanium_ingot.json
index bee6654..8125444 100644
--- a/GameServer/data/gso/items/materials/ingot/titanium_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/titanium_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Titanium Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Titanium Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ingot/tungsten_ingot.json b/GameServer/data/gso/items/materials/ingot/tungsten_ingot.json
index 04cd018..474567d 100644
--- a/GameServer/data/gso/items/materials/ingot/tungsten_ingot.json
+++ b/GameServer/data/gso/items/materials/ingot/tungsten_ingot.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ingot"
+ },
+ "name": "Tungsten Ingot Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Tungsten Ingot Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/liquid/water.json b/GameServer/data/gso/items/materials/liquid/water.json
index a582e19..a2e49ec 100644
--- a/GameServer/data/gso/items/materials/liquid/water.json
+++ b/GameServer/data/gso/items/materials/liquid/water.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "liquid"
+ },
+ "name": "Water Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Water Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/aerospace_aluminum.json b/GameServer/data/gso/items/materials/misc/aerospace_aluminum.json
index 44e03d4..ee8a599 100644
--- a/GameServer/data/gso/items/materials/misc/aerospace_aluminum.json
+++ b/GameServer/data/gso/items/materials/misc/aerospace_aluminum.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Aerospace Aluminum Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Aerospace Aluminum Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/alien_fauna_sample.json b/GameServer/data/gso/items/materials/misc/alien_fauna_sample.json
index 12c4fca..b65d670 100644
--- a/GameServer/data/gso/items/materials/misc/alien_fauna_sample.json
+++ b/GameServer/data/gso/items/materials/misc/alien_fauna_sample.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Alien Fauna Sample Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Alien Fauna Sample Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/alien_protein.json b/GameServer/data/gso/items/materials/misc/alien_protein.json
index e2f0032..0316b53 100644
--- a/GameServer/data/gso/items/materials/misc/alien_protein.json
+++ b/GameServer/data/gso/items/materials/misc/alien_protein.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Alien Protein Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Alien Protein Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/animal_carcass.json b/GameServer/data/gso/items/materials/misc/animal_carcass.json
index a5f7989..4a84035 100644
--- a/GameServer/data/gso/items/materials/misc/animal_carcass.json
+++ b/GameServer/data/gso/items/materials/misc/animal_carcass.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Animal Carcass Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Animal Carcass Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/bandage.json b/GameServer/data/gso/items/materials/misc/bandage.json
index 99b667c..2ba922f 100644
--- a/GameServer/data/gso/items/materials/misc/bandage.json
+++ b/GameServer/data/gso/items/materials/misc/bandage.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Bandage Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Bandage Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/body_exotic.json b/GameServer/data/gso/items/materials/misc/body_exotic.json
index 1ac7c69..ee4afe7 100644
--- a/GameServer/data/gso/items/materials/misc/body_exotic.json
+++ b/GameServer/data/gso/items/materials/misc/body_exotic.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Body Exotic Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Body Exotic Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/body_light.json b/GameServer/data/gso/items/materials/misc/body_light.json
index 47f0e18..859eeba 100644
--- a/GameServer/data/gso/items/materials/misc/body_light.json
+++ b/GameServer/data/gso/items/materials/misc/body_light.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Body Light Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Body Light Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/body_military.json b/GameServer/data/gso/items/materials/misc/body_military.json
index ed810d9..1d528b1 100644
--- a/GameServer/data/gso/items/materials/misc/body_military.json
+++ b/GameServer/data/gso/items/materials/misc/body_military.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Body Military Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Body Military Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/body_standard.json b/GameServer/data/gso/items/materials/misc/body_standard.json
index 865e876..e9c4fde 100644
--- a/GameServer/data/gso/items/materials/misc/body_standard.json
+++ b/GameServer/data/gso/items/materials/misc/body_standard.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Body Standard Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Body Standard Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/boots_light.json b/GameServer/data/gso/items/materials/misc/boots_light.json
index cd3f5a8..ec3e57b 100644
--- a/GameServer/data/gso/items/materials/misc/boots_light.json
+++ b/GameServer/data/gso/items/materials/misc/boots_light.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Boots Light Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Boots Light Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/boots_magnetic.json b/GameServer/data/gso/items/materials/misc/boots_magnetic.json
index b773376..84ad8f2 100644
--- a/GameServer/data/gso/items/materials/misc/boots_magnetic.json
+++ b/GameServer/data/gso/items/materials/misc/boots_magnetic.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Boots Magnetic Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Boots Magnetic Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/boots_military.json b/GameServer/data/gso/items/materials/misc/boots_military.json
index 7b16a29..753cf34 100644
--- a/GameServer/data/gso/items/materials/misc/boots_military.json
+++ b/GameServer/data/gso/items/materials/misc/boots_military.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Boots Military Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Boots Military Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/boots_standard.json b/GameServer/data/gso/items/materials/misc/boots_standard.json
index 502e2a7..7a14488 100644
--- a/GameServer/data/gso/items/materials/misc/boots_standard.json
+++ b/GameServer/data/gso/items/materials/misc/boots_standard.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Boots Standard Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Boots Standard Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/carbon_shale.json b/GameServer/data/gso/items/materials/misc/carbon_shale.json
index 4f0011f..8a0a049 100644
--- a/GameServer/data/gso/items/materials/misc/carbon_shale.json
+++ b/GameServer/data/gso/items/materials/misc/carbon_shale.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Carbon Shale Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Carbon Shale Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/chromium_steel.json b/GameServer/data/gso/items/materials/misc/chromium_steel.json
index 5a38bd2..24e1e9c 100644
--- a/GameServer/data/gso/items/materials/misc/chromium_steel.json
+++ b/GameServer/data/gso/items/materials/misc/chromium_steel.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Chromium Steel Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Chromium Steel Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/cooked_fish.json b/GameServer/data/gso/items/materials/misc/cooked_fish.json
index 04fad5b..744d492 100644
--- a/GameServer/data/gso/items/materials/misc/cooked_fish.json
+++ b/GameServer/data/gso/items/materials/misc/cooked_fish.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Cooked Fish Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Cooked Fish Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/cooked_meat.json b/GameServer/data/gso/items/materials/misc/cooked_meat.json
index f744a82..75e186d 100644
--- a/GameServer/data/gso/items/materials/misc/cooked_meat.json
+++ b/GameServer/data/gso/items/materials/misc/cooked_meat.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Cooked Meat Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Cooked Meat Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/crystal_glass.json b/GameServer/data/gso/items/materials/misc/crystal_glass.json
index ed0dd5c..f692718 100644
--- a/GameServer/data/gso/items/materials/misc/crystal_glass.json
+++ b/GameServer/data/gso/items/materials/misc/crystal_glass.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Crystal Glass Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Crystal Glass Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/dough.json b/GameServer/data/gso/items/materials/misc/dough.json
index eaba2dd..4e46201 100644
--- a/GameServer/data/gso/items/materials/misc/dough.json
+++ b/GameServer/data/gso/items/materials/misc/dough.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Dough Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Dough Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/flux_crystal.json b/GameServer/data/gso/items/materials/misc/flux_crystal.json
index 9bc919f..395eb73 100644
--- a/GameServer/data/gso/items/materials/misc/flux_crystal.json
+++ b/GameServer/data/gso/items/materials/misc/flux_crystal.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Flux Crystal Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Flux Crystal Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/gloves_industrial.json b/GameServer/data/gso/items/materials/misc/gloves_industrial.json
index b734c4b..efa6721 100644
--- a/GameServer/data/gso/items/materials/misc/gloves_industrial.json
+++ b/GameServer/data/gso/items/materials/misc/gloves_industrial.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Gloves Industrial Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Gloves Industrial Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/gloves_light.json b/GameServer/data/gso/items/materials/misc/gloves_light.json
index 90fb50d..7c21263 100644
--- a/GameServer/data/gso/items/materials/misc/gloves_light.json
+++ b/GameServer/data/gso/items/materials/misc/gloves_light.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Gloves Light Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Gloves Light Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/gloves_military.json b/GameServer/data/gso/items/materials/misc/gloves_military.json
index b6df73e..0fdc72b 100644
--- a/GameServer/data/gso/items/materials/misc/gloves_military.json
+++ b/GameServer/data/gso/items/materials/misc/gloves_military.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Gloves Military Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Gloves Military Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/gloves_standard.json b/GameServer/data/gso/items/materials/misc/gloves_standard.json
index 37f29e8..f9eaa97 100644
--- a/GameServer/data/gso/items/materials/misc/gloves_standard.json
+++ b/GameServer/data/gso/items/materials/misc/gloves_standard.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Gloves Standard Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Gloves Standard Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/helmet_exotic.json b/GameServer/data/gso/items/materials/misc/helmet_exotic.json
index ff48b87..1ed866e 100644
--- a/GameServer/data/gso/items/materials/misc/helmet_exotic.json
+++ b/GameServer/data/gso/items/materials/misc/helmet_exotic.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Helmet Exotic Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Helmet Exotic Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/helmet_light.json b/GameServer/data/gso/items/materials/misc/helmet_light.json
index 79da9f9..d8818d4 100644
--- a/GameServer/data/gso/items/materials/misc/helmet_light.json
+++ b/GameServer/data/gso/items/materials/misc/helmet_light.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Helmet Light Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Helmet Light Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/helmet_military.json b/GameServer/data/gso/items/materials/misc/helmet_military.json
index d47135c..9e177cf 100644
--- a/GameServer/data/gso/items/materials/misc/helmet_military.json
+++ b/GameServer/data/gso/items/materials/misc/helmet_military.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Helmet Military Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Helmet Military Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/helmet_standard.json b/GameServer/data/gso/items/materials/misc/helmet_standard.json
index 1211052..e564ff7 100644
--- a/GameServer/data/gso/items/materials/misc/helmet_standard.json
+++ b/GameServer/data/gso/items/materials/misc/helmet_standard.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Helmet Standard Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Helmet Standard Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/hydroponic_growth_medium.json b/GameServer/data/gso/items/materials/misc/hydroponic_growth_medium.json
index 82b2306..413039f 100644
--- a/GameServer/data/gso/items/materials/misc/hydroponic_growth_medium.json
+++ b/GameServer/data/gso/items/materials/misc/hydroponic_growth_medium.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Hydroponic Growth Medium Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Hydroponic Growth Medium Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/ice_chunk.json b/GameServer/data/gso/items/materials/misc/ice_chunk.json
index dca1c4d..dec826d 100644
--- a/GameServer/data/gso/items/materials/misc/ice_chunk.json
+++ b/GameServer/data/gso/items/materials/misc/ice_chunk.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Ice Chunk Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Ice Chunk Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/life_support_basic.json b/GameServer/data/gso/items/materials/misc/life_support_basic.json
index 0bacdba..b8fdb02 100644
--- a/GameServer/data/gso/items/materials/misc/life_support_basic.json
+++ b/GameServer/data/gso/items/materials/misc/life_support_basic.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Life Support Basic Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Life Support Basic Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/life_support_exotic.json b/GameServer/data/gso/items/materials/misc/life_support_exotic.json
index 6b7e48d..90517dd 100644
--- a/GameServer/data/gso/items/materials/misc/life_support_exotic.json
+++ b/GameServer/data/gso/items/materials/misc/life_support_exotic.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Life Support Exotic Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Life Support Exotic Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/life_support_military.json b/GameServer/data/gso/items/materials/misc/life_support_military.json
index 99e6d10..245d1ce 100644
--- a/GameServer/data/gso/items/materials/misc/life_support_military.json
+++ b/GameServer/data/gso/items/materials/misc/life_support_military.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Life Support Military Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Life Support Military Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/life_support_standard.json b/GameServer/data/gso/items/materials/misc/life_support_standard.json
index e595921..bb69964 100644
--- a/GameServer/data/gso/items/materials/misc/life_support_standard.json
+++ b/GameServer/data/gso/items/materials/misc/life_support_standard.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Life Support Standard Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Life Support Standard Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/luxury_meal.json b/GameServer/data/gso/items/materials/misc/luxury_meal.json
index c172420..14b3d63 100644
--- a/GameServer/data/gso/items/materials/misc/luxury_meal.json
+++ b/GameServer/data/gso/items/materials/misc/luxury_meal.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Luxury Meal Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Luxury Meal Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/magnetic_coil.json b/GameServer/data/gso/items/materials/misc/magnetic_coil.json
index 6821764..4e5edc1 100644
--- a/GameServer/data/gso/items/materials/misc/magnetic_coil.json
+++ b/GameServer/data/gso/items/materials/misc/magnetic_coil.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Magnetic Coil Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Magnetic Coil Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/medical_pack.json b/GameServer/data/gso/items/materials/misc/medical_pack.json
index a383c69..2631c69 100644
--- a/GameServer/data/gso/items/materials/misc/medical_pack.json
+++ b/GameServer/data/gso/items/materials/misc/medical_pack.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Medical Pack Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Medical Pack Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/military_ration.json b/GameServer/data/gso/items/materials/misc/military_ration.json
index 0d32df0..becf07e 100644
--- a/GameServer/data/gso/items/materials/misc/military_ration.json
+++ b/GameServer/data/gso/items/materials/misc/military_ration.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Military Ration Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Military Ration Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/neutronium_shard.json b/GameServer/data/gso/items/materials/misc/neutronium_shard.json
index ac6591e..e4441b4 100644
--- a/GameServer/data/gso/items/materials/misc/neutronium_shard.json
+++ b/GameServer/data/gso/items/materials/misc/neutronium_shard.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Neutronium Shard Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Neutronium Shard Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/nutrient_paste.json b/GameServer/data/gso/items/materials/misc/nutrient_paste.json
index 5f7ba9f..6a0404a 100644
--- a/GameServer/data/gso/items/materials/misc/nutrient_paste.json
+++ b/GameServer/data/gso/items/materials/misc/nutrient_paste.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Nutrient Paste Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Nutrient Paste Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/pants_exotic.json b/GameServer/data/gso/items/materials/misc/pants_exotic.json
index f321099..3ef3d8e 100644
--- a/GameServer/data/gso/items/materials/misc/pants_exotic.json
+++ b/GameServer/data/gso/items/materials/misc/pants_exotic.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Pants Exotic Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Pants Exotic Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/pants_heavy.json b/GameServer/data/gso/items/materials/misc/pants_heavy.json
index 4e7b70a..0405d35 100644
--- a/GameServer/data/gso/items/materials/misc/pants_heavy.json
+++ b/GameServer/data/gso/items/materials/misc/pants_heavy.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Pants Heavy Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Pants Heavy Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/pants_light.json b/GameServer/data/gso/items/materials/misc/pants_light.json
index e54f1b0..a00f3b1 100644
--- a/GameServer/data/gso/items/materials/misc/pants_light.json
+++ b/GameServer/data/gso/items/materials/misc/pants_light.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Pants Light Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Pants Light Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/pants_standard.json b/GameServer/data/gso/items/materials/misc/pants_standard.json
index 8bbd979..898b868 100644
--- a/GameServer/data/gso/items/materials/misc/pants_standard.json
+++ b/GameServer/data/gso/items/materials/misc/pants_standard.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Pants Standard Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Pants Standard Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/phase_crystal.json b/GameServer/data/gso/items/materials/misc/phase_crystal.json
index 0365dbb..fb2027c 100644
--- a/GameServer/data/gso/items/materials/misc/phase_crystal.json
+++ b/GameServer/data/gso/items/materials/misc/phase_crystal.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Phase Crystal Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Phase Crystal Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/processed_wood.json b/GameServer/data/gso/items/materials/misc/processed_wood.json
index c856c4a..aa2f2d8 100644
--- a/GameServer/data/gso/items/materials/misc/processed_wood.json
+++ b/GameServer/data/gso/items/materials/misc/processed_wood.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Processed Wood Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Processed Wood Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/protein_bar.json b/GameServer/data/gso/items/materials/misc/protein_bar.json
index c1e9309..62d9363 100644
--- a/GameServer/data/gso/items/materials/misc/protein_bar.json
+++ b/GameServer/data/gso/items/materials/misc/protein_bar.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Protein Bar Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Protein Bar Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/raw_fruits.json b/GameServer/data/gso/items/materials/misc/raw_fruits.json
index 2c89214..31a6eaf 100644
--- a/GameServer/data/gso/items/materials/misc/raw_fruits.json
+++ b/GameServer/data/gso/items/materials/misc/raw_fruits.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Raw Fruits Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Raw Fruits Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/raw_meat.json b/GameServer/data/gso/items/materials/misc/raw_meat.json
index 04380f6..9a89242 100644
--- a/GameServer/data/gso/items/materials/misc/raw_meat.json
+++ b/GameServer/data/gso/items/materials/misc/raw_meat.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Raw Meat Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Raw Meat Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/raw_vegetables.json b/GameServer/data/gso/items/materials/misc/raw_vegetables.json
index 5eced33..a460296 100644
--- a/GameServer/data/gso/items/materials/misc/raw_vegetables.json
+++ b/GameServer/data/gso/items/materials/misc/raw_vegetables.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Raw Vegetables Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Raw Vegetables Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/raw_wood.json b/GameServer/data/gso/items/materials/misc/raw_wood.json
index e823203..dcdd8d6 100644
--- a/GameServer/data/gso/items/materials/misc/raw_wood.json
+++ b/GameServer/data/gso/items/materials/misc/raw_wood.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Raw Wood Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Raw Wood Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/silicon_wafer.json b/GameServer/data/gso/items/materials/misc/silicon_wafer.json
index bd28e1b..fbf9311 100644
--- a/GameServer/data/gso/items/materials/misc/silicon_wafer.json
+++ b/GameServer/data/gso/items/materials/misc/silicon_wafer.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Silicon Wafer Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Silicon Wafer Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/tree.json b/GameServer/data/gso/items/materials/misc/tree.json
index f0c9fd8..842b7c1 100644
--- a/GameServer/data/gso/items/materials/misc/tree.json
+++ b/GameServer/data/gso/items/materials/misc/tree.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Tree Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Tree Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/tree_sap.json b/GameServer/data/gso/items/materials/misc/tree_sap.json
index 2acae8e..c28c8b6 100644
--- a/GameServer/data/gso/items/materials/misc/tree_sap.json
+++ b/GameServer/data/gso/items/materials/misc/tree_sap.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Tree Sap Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Tree Sap Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/tungsten_steel.json b/GameServer/data/gso/items/materials/misc/tungsten_steel.json
index 072f02c..c10c4ef 100644
--- a/GameServer/data/gso/items/materials/misc/tungsten_steel.json
+++ b/GameServer/data/gso/items/materials/misc/tungsten_steel.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Tungsten Steel Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Tungsten Steel Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/void_crystal.json b/GameServer/data/gso/items/materials/misc/void_crystal.json
index 2959095..ff7e382 100644
--- a/GameServer/data/gso/items/materials/misc/void_crystal.json
+++ b/GameServer/data/gso/items/materials/misc/void_crystal.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Void Crystal Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Void Crystal Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/void_residue.json b/GameServer/data/gso/items/materials/misc/void_residue.json
index 51b1851..e022b27 100644
--- a/GameServer/data/gso/items/materials/misc/void_residue.json
+++ b/GameServer/data/gso/items/materials/misc/void_residue.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Void Residue Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Void Residue Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/misc/wooden_components.json b/GameServer/data/gso/items/materials/misc/wooden_components.json
index 7e524b4..88006da 100644
--- a/GameServer/data/gso/items/materials/misc/wooden_components.json
+++ b/GameServer/data/gso/items/materials/misc/wooden_components.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "misc"
+ },
+ "name": "Wooden Components Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Wooden Components Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/bauxite_ore.json b/GameServer/data/gso/items/materials/ore/bauxite_ore.json
index 67239c3..d777a4c 100644
--- a/GameServer/data/gso/items/materials/ore/bauxite_ore.json
+++ b/GameServer/data/gso/items/materials/ore/bauxite_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Bauxite Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Bauxite Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/chromium_ore.json b/GameServer/data/gso/items/materials/ore/chromium_ore.json
index 4b2dfe6..3daf8be 100644
--- a/GameServer/data/gso/items/materials/ore/chromium_ore.json
+++ b/GameServer/data/gso/items/materials/ore/chromium_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Chromium Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Chromium Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/chronite_ore.json b/GameServer/data/gso/items/materials/ore/chronite_ore.json
index 8b3b6cc..3d26110 100644
--- a/GameServer/data/gso/items/materials/ore/chronite_ore.json
+++ b/GameServer/data/gso/items/materials/ore/chronite_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Chronite Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Chronite Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/copper_ore.json b/GameServer/data/gso/items/materials/ore/copper_ore.json
index ae7c850..0f4eac3 100644
--- a/GameServer/data/gso/items/materials/ore/copper_ore.json
+++ b/GameServer/data/gso/items/materials/ore/copper_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Copper Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Copper Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/dark_iron_ore.json b/GameServer/data/gso/items/materials/ore/dark_iron_ore.json
index 4a5b5b2..307f851 100644
--- a/GameServer/data/gso/items/materials/ore/dark_iron_ore.json
+++ b/GameServer/data/gso/items/materials/ore/dark_iron_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Dark Iron Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Dark Iron Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/gold_ore.json b/GameServer/data/gso/items/materials/ore/gold_ore.json
index 463cd2b..1cacaec 100644
--- a/GameServer/data/gso/items/materials/ore/gold_ore.json
+++ b/GameServer/data/gso/items/materials/ore/gold_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Gold Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Gold Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/iron_ore.json b/GameServer/data/gso/items/materials/ore/iron_ore.json
index bbd8d8a..63acb28 100644
--- a/GameServer/data/gso/items/materials/ore/iron_ore.json
+++ b/GameServer/data/gso/items/materials/ore/iron_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Iron Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Iron Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/magnesium_ore.json b/GameServer/data/gso/items/materials/ore/magnesium_ore.json
index 47f162e..ce8b49d 100644
--- a/GameServer/data/gso/items/materials/ore/magnesium_ore.json
+++ b/GameServer/data/gso/items/materials/ore/magnesium_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Magnesium Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Magnesium Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/platinum_ore.json b/GameServer/data/gso/items/materials/ore/platinum_ore.json
index bd044b6..70a5396 100644
--- a/GameServer/data/gso/items/materials/ore/platinum_ore.json
+++ b/GameServer/data/gso/items/materials/ore/platinum_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Platinum Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Platinum Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/silver_ore.json b/GameServer/data/gso/items/materials/ore/silver_ore.json
index 93a220f..f0d176c 100644
--- a/GameServer/data/gso/items/materials/ore/silver_ore.json
+++ b/GameServer/data/gso/items/materials/ore/silver_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Silver Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Silver Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/titanium_ore.json b/GameServer/data/gso/items/materials/ore/titanium_ore.json
index 045c5ca..03ba74d 100644
--- a/GameServer/data/gso/items/materials/ore/titanium_ore.json
+++ b/GameServer/data/gso/items/materials/ore/titanium_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Titanium Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Titanium Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/ore/tungsten_ore.json b/GameServer/data/gso/items/materials/ore/tungsten_ore.json
index 56ee49f..9d8e1cb 100644
--- a/GameServer/data/gso/items/materials/ore/tungsten_ore.json
+++ b/GameServer/data/gso/items/materials/ore/tungsten_ore.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "ore"
+ },
+ "name": "Tungsten Ore Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Tungsten Ore Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/stone/fluxstone.json b/GameServer/data/gso/items/materials/stone/fluxstone.json
index 073b760..c4d06c1 100644
--- a/GameServer/data/gso/items/materials/stone/fluxstone.json
+++ b/GameServer/data/gso/items/materials/stone/fluxstone.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "stone"
+ },
+ "name": "Fluxstone Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Fluxstone Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/materials/wood/wood_planks.json b/GameServer/data/gso/items/materials/wood/wood_planks.json
index bdc7092..a5f33b4 100644
--- a/GameServer/data/gso/items/materials/wood/wood_planks.json
+++ b/GameServer/data/gso/items/materials/wood/wood_planks.json
@@ -6,6 +6,20 @@
"stats": [],
"meta": {
"materialCategory": "wood"
+ },
+ "name": "Wood Planks Common",
+ "type": "materials",
+ "rarity": "common",
+ "price": 500,
+ "currency": "credits",
+ "description": "Wood Planks Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "stackable": true,
+ "requirements": {
+ "level": 1
}
}
}
diff --git a/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_common.json b/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_common.json
deleted file mode 100644
index 3fff28b..0000000
--- a/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "assault_rifle_common",
- "texture": "assets/gso/textures/weapon/assaultrifle/assault_rifle_common.png",
- "stats": {
- "damage": 26,
- "criticalChance": 0.04,
- "attackRate": 6
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_epic.json b/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_epic.json
deleted file mode 100644
index b9964bb..0000000
--- a/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "assault_rifle_epic",
- "texture": "assets/gso/textures/weapon/assaultrifle/assault_rifle_epic.png",
- "stats": {
- "damage": 56,
- "criticalChance": 0.14,
- "attackRate": 8
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_rare.json b/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_rare.json
deleted file mode 100644
index 4bef56d..0000000
--- a/GameServer/data/gso/items/weapon/assaultrifle/assault_rifle_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "assault_rifle_rare",
- "texture": "assets/gso/textures/weapon/assaultrifle/assault_rifle_rare.png",
- "stats": {
- "damage": 38,
- "criticalChance": 0.08,
- "attackRate": 7
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_common.json b/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_common.json
deleted file mode 100644
index 12d45fb..0000000
--- a/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "dual_pistol_common",
- "texture": "assets/gso/textures/weapon/dualpistol/dual_pistol_common.png",
- "stats": {
- "damage": 14,
- "criticalChance": 0.06,
- "attackRate": 7
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_epic.json b/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_epic.json
deleted file mode 100644
index 541f57a..0000000
--- a/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "dual_pistol_epic",
- "texture": "assets/gso/textures/weapon/dualpistol/dual_pistol_epic.png",
- "stats": {
- "damage": 34,
- "criticalChance": 0.2,
- "attackRate": 11
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_rare.json b/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_rare.json
deleted file mode 100644
index bb91d2c..0000000
--- a/GameServer/data/gso/items/weapon/dualpistol/dual_pistol_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "dual_pistol_rare",
- "texture": "assets/gso/textures/weapon/dualpistol/dual_pistol_rare.png",
- "stats": {
- "damage": 22,
- "criticalChance": 0.12,
- "attackRate": 9
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/laserbow/laser_bow_common.json b/GameServer/data/gso/items/weapon/laserbow/laser_bow_common.json
deleted file mode 100644
index f421632..0000000
--- a/GameServer/data/gso/items/weapon/laserbow/laser_bow_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "laser_bow_common",
- "texture": "assets/gso/textures/weapon/laserbow/laser_bow_common.png",
- "stats": {
- "damage": 40,
- "criticalChance": 0.18,
- "attackRate": 3
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/laserbow/laser_bow_epic.json b/GameServer/data/gso/items/weapon/laserbow/laser_bow_epic.json
deleted file mode 100644
index 63c290a..0000000
--- a/GameServer/data/gso/items/weapon/laserbow/laser_bow_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "laser_bow_epic",
- "texture": "assets/gso/textures/weapon/laserbow/laser_bow_epic.png",
- "stats": {
- "damage": 95,
- "criticalChance": 0.45,
- "attackRate": 4
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/laserbow/laser_bow_rare.json b/GameServer/data/gso/items/weapon/laserbow/laser_bow_rare.json
deleted file mode 100644
index 1a5813b..0000000
--- a/GameServer/data/gso/items/weapon/laserbow/laser_bow_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "laser_bow_rare",
- "texture": "assets/gso/textures/weapon/laserbow/laser_bow_rare.png",
- "stats": {
- "damage": 62,
- "criticalChance": 0.3,
- "attackRate": 4
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_common.json b/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_common.json
deleted file mode 100644
index 1e84817..0000000
--- a/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "laser_crossbow_common",
- "texture": "assets/gso/textures/weapon/lasercrossbow/laser_crossbow_common.png",
- "stats": {
- "damage": 48,
- "criticalChance": 0.15,
- "attackRate": 2
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_epic.json b/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_epic.json
deleted file mode 100644
index 93692b6..0000000
--- a/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "laser_crossbow_epic",
- "texture": "assets/gso/textures/weapon/lasercrossbow/laser_crossbow_epic.png",
- "stats": {
- "damage": 110,
- "criticalChance": 0.4,
- "attackRate": 3
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_rare.json b/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_rare.json
deleted file mode 100644
index be4921c..0000000
--- a/GameServer/data/gso/items/weapon/lasercrossbow/laser_crossbow_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "laser_crossbow_rare",
- "texture": "assets/gso/textures/weapon/lasercrossbow/laser_crossbow_rare.png",
- "stats": {
- "damage": 72,
- "criticalChance": 0.25,
- "attackRate": 3
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/pistol/pistol_marksman_rare.json b/GameServer/data/gso/items/weapon/pistol/pistol_marksman_rare.json
deleted file mode 100644
index 7f03a00..0000000
--- a/GameServer/data/gso/items/weapon/pistol/pistol_marksman_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "pistol_marksman_rare",
- "texture": "assets/gso/textures/weapon/pistol/pistol_marksman_rare.png",
- "stats": {
- "damage": 28,
- "criticalChance": 0.1,
- "attackRate": 5
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/pistol/pistol_overcharge_epic.json b/GameServer/data/gso/items/weapon/pistol/pistol_overcharge_epic.json
deleted file mode 100644
index d7206b6..0000000
--- a/GameServer/data/gso/items/weapon/pistol/pistol_overcharge_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "pistol_overcharge_epic",
- "texture": "assets/gso/textures/weapon/pistol/pistol_overcharge_epic.png",
- "stats": {
- "damage": 42,
- "criticalChance": 0.18,
- "attackRate": 6
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/pistol/pistol_standard_common.json b/GameServer/data/gso/items/weapon/pistol/pistol_standard_common.json
deleted file mode 100644
index 4d219d6..0000000
--- a/GameServer/data/gso/items/weapon/pistol/pistol_standard_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "pistol_standard_common",
- "texture": "assets/gso/textures/weapon/pistol/pistol_standard_common.png",
- "stats": {
- "damage": 18,
- "criticalChance": 0.05,
- "attackRate": 4
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_common.json b/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_common.json
deleted file mode 100644
index 2bda647..0000000
--- a/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "plasma_cutter_common",
- "texture": "assets/gso/textures/weapon/plasmacutter/plasma_cutter_common.png",
- "stats": {
- "damage": 60,
- "criticalChance": 0.12,
- "attackRate": 3
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_epic.json b/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_epic.json
deleted file mode 100644
index f6700d1..0000000
--- a/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "plasma_cutter_epic",
- "texture": "assets/gso/textures/weapon/plasmacutter/plasma_cutter_epic.png",
- "stats": {
- "damage": 135,
- "criticalChance": 0.35,
- "attackRate": 5
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_rare.json b/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_rare.json
deleted file mode 100644
index 0cc02a0..0000000
--- a/GameServer/data/gso/items/weapon/plasmacutter/plasma_cutter_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "plasma_cutter_rare",
- "texture": "assets/gso/textures/weapon/plasmacutter/plasma_cutter_rare.png",
- "stats": {
- "damage": 90,
- "criticalChance": 0.2,
- "attackRate": 4
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_common.json b/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_common.json
deleted file mode 100644
index cdb832c..0000000
--- a/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "rocket_launcher_common",
- "texture": "assets/gso/textures/weapon/rocketlauncher/rocket_launcher_common.png",
- "stats": {
- "damage": 140,
- "criticalChance": 0.1,
- "attackRate": 1
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_epic.json b/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_epic.json
deleted file mode 100644
index 9d80a49..0000000
--- a/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "rocket_launcher_epic",
- "texture": "assets/gso/textures/weapon/rocketlauncher/rocket_launcher_epic.png",
- "stats": {
- "damage": 320,
- "criticalChance": 0.25,
- "attackRate": 2
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_rare.json b/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_rare.json
deleted file mode 100644
index d9f7bb0..0000000
--- a/GameServer/data/gso/items/weapon/rocketlauncher/rocket_launcher_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "rocket_launcher_rare",
- "texture": "assets/gso/textures/weapon/rocketlauncher/rocket_launcher_rare.png",
- "stats": {
- "damage": 220,
- "criticalChance": 0.18,
- "attackRate": 1
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/sniper/sniper_common.json b/GameServer/data/gso/items/weapon/sniper/sniper_common.json
deleted file mode 100644
index f5f3cac..0000000
--- a/GameServer/data/gso/items/weapon/sniper/sniper_common.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "sniper_common",
- "texture": "assets/gso/textures/weapon/sniper/sniper_common.png",
- "stats": {
- "damage": 90,
- "criticalChance": 0.2,
- "attackRate": 1
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/sniper/sniper_epic.json b/GameServer/data/gso/items/weapon/sniper/sniper_epic.json
deleted file mode 100644
index 6789b70..0000000
--- a/GameServer/data/gso/items/weapon/sniper/sniper_epic.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "sniper_epic",
- "texture": "assets/gso/textures/weapon/sniper/sniper_epic.png",
- "stats": {
- "damage": 190,
- "criticalChance": 0.45,
- "attackRate": 2
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapon/sniper/sniper_rare.json b/GameServer/data/gso/items/weapon/sniper/sniper_rare.json
deleted file mode 100644
index bbbd9e4..0000000
--- a/GameServer/data/gso/items/weapon/sniper/sniper_rare.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "templates": {
- "weapon": {
- "id": "sniper_rare",
- "texture": "assets/gso/textures/weapon/sniper/sniper_rare.png",
- "stats": {
- "damage": 135,
- "criticalChance": 0.3,
- "attackRate": 1
- }
- }
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/assault_rifle_epic.json b/GameServer/data/gso/items/weapons/assault_rifle_epic.json
new file mode 100644
index 0000000..69c6d8e
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/assault_rifle_epic.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "assault_rifle_epic",
+ "texture": "assets/gso/textures/weapon/assaultrifle/assault_rifle_epic.png",
+ "stats": {
+ "damage": 56,
+ "criticalChance": 0.14,
+ "attackRate": 8
+ },
+ "name": "Assault Rifle Epic",
+ "type": "weapon",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Assault Rifle Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/dual_pistol_common.json b/GameServer/data/gso/items/weapons/dual_pistol_common.json
new file mode 100644
index 0000000..02ced3b
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/dual_pistol_common.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "dual_pistol_common",
+ "texture": "assets/gso/textures/weapon/dualpistol/dual_pistol_common.png",
+ "stats": {
+ "damage": 14,
+ "criticalChance": 0.06,
+ "attackRate": 7
+ },
+ "name": "Dual Pistol Common",
+ "type": "weapon",
+ "rarity": "common",
+ "price": 1000,
+ "currency": "credits",
+ "description": "Dual Pistol Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 1
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/dual_pistol_epic.json b/GameServer/data/gso/items/weapons/dual_pistol_epic.json
new file mode 100644
index 0000000..08e90dc
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/dual_pistol_epic.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "dual_pistol_epic",
+ "texture": "assets/gso/textures/weapon/dualpistol/dual_pistol_epic.png",
+ "stats": {
+ "damage": 34,
+ "criticalChance": 0.2,
+ "attackRate": 11
+ },
+ "name": "Dual Pistol Epic",
+ "type": "weapon",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Dual Pistol Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/dual_pistol_rare.json b/GameServer/data/gso/items/weapons/dual_pistol_rare.json
new file mode 100644
index 0000000..99e0e0b
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/dual_pistol_rare.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "dual_pistol_rare",
+ "texture": "assets/gso/textures/weapon/dualpistol/dual_pistol_rare.png",
+ "stats": {
+ "damage": 22,
+ "criticalChance": 0.12,
+ "attackRate": 9
+ },
+ "name": "Dual Pistol Rare",
+ "type": "weapon",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Dual Pistol Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/laser_bow_common.json b/GameServer/data/gso/items/weapons/laser_bow_common.json
new file mode 100644
index 0000000..8351144
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/laser_bow_common.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "laser_bow_common",
+ "texture": "assets/gso/textures/weapon/laserbow/laser_bow_common.png",
+ "stats": {
+ "damage": 40,
+ "criticalChance": 0.18,
+ "attackRate": 3
+ },
+ "name": "Laser Bow Common",
+ "type": "weapon",
+ "rarity": "common",
+ "price": 1000,
+ "currency": "credits",
+ "description": "Laser Bow Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 1
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/laser_bow_rare.json b/GameServer/data/gso/items/weapons/laser_bow_rare.json
new file mode 100644
index 0000000..0f29c06
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/laser_bow_rare.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "laser_bow_rare",
+ "texture": "assets/gso/textures/weapon/laserbow/laser_bow_rare.png",
+ "stats": {
+ "damage": 62,
+ "criticalChance": 0.3,
+ "attackRate": 4
+ },
+ "name": "Laser Bow Rare",
+ "type": "weapon",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Laser Bow Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/laser_crossbow_common.json b/GameServer/data/gso/items/weapons/laser_crossbow_common.json
new file mode 100644
index 0000000..e44585c
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/laser_crossbow_common.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "laser_crossbow_common",
+ "texture": "assets/gso/textures/weapon/lasercrossbow/laser_crossbow_common.png",
+ "stats": {
+ "damage": 48,
+ "criticalChance": 0.15,
+ "attackRate": 2
+ },
+ "name": "Laser Crossbow Common",
+ "type": "weapon",
+ "rarity": "common",
+ "price": 1000,
+ "currency": "credits",
+ "description": "Laser Crossbow Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 1
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/laser_crossbow_epic.json b/GameServer/data/gso/items/weapons/laser_crossbow_epic.json
new file mode 100644
index 0000000..5d62f96
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/laser_crossbow_epic.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "laser_crossbow_epic",
+ "texture": "assets/gso/textures/weapon/lasercrossbow/laser_crossbow_epic.png",
+ "stats": {
+ "damage": 110,
+ "criticalChance": 0.4,
+ "attackRate": 3
+ },
+ "name": "Laser Crossbow Epic",
+ "type": "weapon",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Laser Crossbow Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/laser_crossbow_rare.json b/GameServer/data/gso/items/weapons/laser_crossbow_rare.json
new file mode 100644
index 0000000..208d5ea
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/laser_crossbow_rare.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "laser_crossbow_rare",
+ "texture": "assets/gso/textures/weapon/lasercrossbow/laser_crossbow_rare.png",
+ "stats": {
+ "damage": 72,
+ "criticalChance": 0.25,
+ "attackRate": 3
+ },
+ "name": "Laser Crossbow Rare",
+ "type": "weapon",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Laser Crossbow Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/pistol_overcharge_epic.json b/GameServer/data/gso/items/weapons/pistol_overcharge_epic.json
new file mode 100644
index 0000000..eb6e82a
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/pistol_overcharge_epic.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "pistol_overcharge_epic",
+ "texture": "assets/gso/textures/weapon/pistol/pistol_overcharge_epic.png",
+ "stats": {
+ "damage": 42,
+ "criticalChance": 0.18,
+ "attackRate": 6
+ },
+ "name": "Pistol Overcharge Epic",
+ "type": "weapon",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Pistol Overcharge Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/plasma_cutter_common.json b/GameServer/data/gso/items/weapons/plasma_cutter_common.json
new file mode 100644
index 0000000..3a8ae24
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/plasma_cutter_common.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "plasma_cutter_common",
+ "texture": "assets/gso/textures/weapon/plasmacutter/plasma_cutter_common.png",
+ "stats": {
+ "damage": 60,
+ "criticalChance": 0.12,
+ "attackRate": 3
+ },
+ "name": "Plasma Cutter Common",
+ "type": "weapon",
+ "rarity": "common",
+ "price": 1000,
+ "currency": "credits",
+ "description": "Plasma Cutter Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 1
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/plasma_cutter_epic.json b/GameServer/data/gso/items/weapons/plasma_cutter_epic.json
new file mode 100644
index 0000000..da00418
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/plasma_cutter_epic.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "plasma_cutter_epic",
+ "texture": "assets/gso/textures/weapon/plasmacutter/plasma_cutter_epic.png",
+ "stats": {
+ "damage": 135,
+ "criticalChance": 0.35,
+ "attackRate": 5
+ },
+ "name": "Plasma Cutter Epic",
+ "type": "weapon",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Plasma Cutter Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/rocket_launcher_common.json b/GameServer/data/gso/items/weapons/rocket_launcher_common.json
new file mode 100644
index 0000000..8ed8b64
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/rocket_launcher_common.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "rocket_launcher_common",
+ "texture": "assets/gso/textures/weapon/rocketlauncher/rocket_launcher_common.png",
+ "stats": {
+ "damage": 140,
+ "criticalChance": 0.1,
+ "attackRate": 1
+ },
+ "name": "Rocket Launcher Common",
+ "type": "weapon",
+ "rarity": "common",
+ "price": 1000,
+ "currency": "credits",
+ "description": "Rocket Launcher Common.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 1
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/rocket_launcher_epic.json b/GameServer/data/gso/items/weapons/rocket_launcher_epic.json
new file mode 100644
index 0000000..3736a8f
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/rocket_launcher_epic.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "rocket_launcher_epic",
+ "texture": "assets/gso/textures/weapon/rocketlauncher/rocket_launcher_epic.png",
+ "stats": {
+ "damage": 320,
+ "criticalChance": 0.25,
+ "attackRate": 2
+ },
+ "name": "Rocket Launcher Epic",
+ "type": "weapon",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Rocket Launcher Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/rocket_launcher_rare.json b/GameServer/data/gso/items/weapons/rocket_launcher_rare.json
new file mode 100644
index 0000000..b020107
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/rocket_launcher_rare.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "rocket_launcher_rare",
+ "texture": "assets/gso/textures/weapon/rocketlauncher/rocket_launcher_rare.png",
+ "stats": {
+ "damage": 220,
+ "criticalChance": 0.18,
+ "attackRate": 1
+ },
+ "name": "Rocket Launcher Rare",
+ "type": "weapon",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Rocket Launcher Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/sniper_epic.json b/GameServer/data/gso/items/weapons/sniper_epic.json
new file mode 100644
index 0000000..8aa9bef
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/sniper_epic.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "sniper_epic",
+ "texture": "assets/gso/textures/weapon/sniper/sniper_epic.png",
+ "stats": {
+ "damage": 190,
+ "criticalChance": 0.45,
+ "attackRate": 2
+ },
+ "name": "Sniper Epic",
+ "type": "weapon",
+ "rarity": "epic",
+ "price": 8000,
+ "currency": "credits",
+ "description": "Sniper Epic.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 10
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/items/weapons/sniper_rare.json b/GameServer/data/gso/items/weapons/sniper_rare.json
new file mode 100644
index 0000000..5b13d86
--- /dev/null
+++ b/GameServer/data/gso/items/weapons/sniper_rare.json
@@ -0,0 +1,27 @@
+{
+ "templates": {
+ "weapon": {
+ "id": "sniper_rare",
+ "texture": "assets/gso/textures/weapon/sniper/sniper_rare.png",
+ "stats": {
+ "damage": 135,
+ "criticalChance": 0.3,
+ "attackRate": 1
+ },
+ "name": "Sniper Rare",
+ "type": "weapon",
+ "rarity": "rare",
+ "price": 3000,
+ "currency": "credits",
+ "description": "Sniper Rare.",
+ "categories": [
+ "shop",
+ "dungeon_loot"
+ ],
+ "requirements": {
+ "level": 5
+ },
+ "stackable": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/GameServer/data/gso/skills/combat.json b/GameServer/data/gso/skills/combat.json
deleted file mode 100644
index fdc4eb5..0000000
--- a/GameServer/data/gso/skills/combat.json
+++ /dev/null
@@ -1,48 +0,0 @@
-[
- {
- "id": "weapons_mastery",
- "name": "Weapons Mastery",
- "description": "Increases damage and accuracy with all weapons",
- "category": "combat",
- "maxLevel": 100,
- "experiencePerLevel": 1000,
- "defaultUnlocked": true,
- "icon": "fa-crosshairs",
- "bonuses": { "damage": 2, "accuracy": 1, "criticalChance": 0.5 }
- },
- {
- "id": "defense_training",
- "name": "Defense Training",
- "description": "Improves damage reduction and resistance",
- "category": "combat",
- "maxLevel": 100,
- "experiencePerLevel": 1000,
- "defaultUnlocked": true,
- "icon": "fa-shield-alt",
- "bonuses": { "damageReduction": 1.5, "resistance": 1, "health": 5 }
- },
- {
- "id": "speed_reflexes",
- "name": "Speed & Reflexes",
- "description": "Enhances movement speed and reaction time",
- "category": "combat",
- "maxLevel": 100,
- "experiencePerLevel": 1000,
- "defaultUnlocked": false,
- "requiredLevel": 5,
- "icon": "fa-bolt",
- "bonuses": { "speed": 2, "dodgeChance": 0.8, "initiative": 1 }
- },
- {
- "id": "tactical_analysis",
- "name": "Tactical Analysis",
- "description": "Reveals enemy weaknesses and improves accuracy",
- "category": "combat",
- "maxLevel": 100,
- "experiencePerLevel": 1200,
- "defaultUnlocked": false,
- "requiredLevel": 10,
- "icon": "fa-brain",
- "bonuses": { "criticalDamage": 0.05, "attack": 1 }
- }
-]
diff --git a/GameServer/data/gso/skills/crafting.json b/GameServer/data/gso/skills/crafting.json
deleted file mode 100644
index 5e60722..0000000
--- a/GameServer/data/gso/skills/crafting.json
+++ /dev/null
@@ -1,48 +0,0 @@
-[
- {
- "id": "weapons_crafting",
- "name": "Weapons Crafting",
- "description": "Ability to craft and improve weapons",
- "category": "crafting",
- "maxLevel": 100,
- "experiencePerLevel": 800,
- "defaultUnlocked": true,
- "icon": "fa-hammer",
- "bonuses": { "craftingSpeed": 2, "craftingSuccess": 1, "rareChance": 0.5 }
- },
- {
- "id": "armor_crafting",
- "name": "Armor Crafting",
- "description": "Ability to craft and improve armor",
- "category": "crafting",
- "maxLevel": 100,
- "experiencePerLevel": 800,
- "defaultUnlocked": true,
- "icon": "fa-hard-hat",
- "bonuses": { "craftingSpeed": 2, "durabilityBonus": 3, "rareChance": 0.5 }
- },
- {
- "id": "resource_extraction",
- "name": "Resource Extraction",
- "description": "Better resource gathering and efficiency",
- "category": "crafting",
- "maxLevel": 100,
- "experiencePerLevel": 700,
- "defaultUnlocked": false,
- "requiredLevel": 4,
- "icon": "fa-gem",
- "bonuses": { "resourceBonus": 0.15, "findResources": 0.1 }
- },
- {
- "id": "engineering",
- "name": "Engineering",
- "description": "Advanced ship modifications and systems",
- "category": "crafting",
- "maxLevel": 100,
- "experiencePerLevel": 1000,
- "defaultUnlocked": false,
- "requiredLevel": 7,
- "icon": "fa-cogs",
- "bonuses": { "shipUpgrades": 0.2, "systemEfficiency": 0.1 }
- }
-]
diff --git a/GameServer/data/gso/skills/crafting/general_crafting.json b/GameServer/data/gso/skills/crafting/general_crafting.json
deleted file mode 100644
index 18cd89f..0000000
--- a/GameServer/data/gso/skills/crafting/general_crafting.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "id": "general_crafting",
- "name": "General Crafting",
- "category": "crafting",
- "description": "Foundation crafting skills for all item types",
- "maxLevel": 100,
- "experiencePerLevel": 800,
- "defaultUnlocked": true,
- "icon": "fa-hammer",
- "bonuses": {
- "craftingBonus": 0.05,
- "craftingSpeed": 1
- }
-}
\ No newline at end of file
diff --git a/GameServer/data/gso/skills/science.json b/GameServer/data/gso/skills/science.json
deleted file mode 100644
index 237f554..0000000
--- a/GameServer/data/gso/skills/science.json
+++ /dev/null
@@ -1,49 +0,0 @@
-[
- {
- "id": "energy_manipulation",
- "name": "Energy Manipulation",
- "description": "Better energy control and regeneration",
- "category": "science",
- "maxLevel": 100,
- "experiencePerLevel": 1000,
- "defaultUnlocked": true,
- "icon": "fa-bolt",
- "bonuses": { "maxEnergy": 10, "energyRegeneration": 0.1 }
- },
- {
- "id": "alien_technology",
- "name": "Alien Technology",
- "description": "Understanding and using alien artifacts",
- "category": "science",
- "maxLevel": 100,
- "experiencePerLevel": 1200,
- "defaultUnlocked": false,
- "requiredLevel": 3,
- "icon": "fa-atom",
- "bonuses": { "findRarity": 0.05, "itemValue": 0.1 }
- },
- {
- "id": "quantum_physics",
- "name": "Quantum Physics",
- "description": "Advanced quantum mechanics for better equipment",
- "category": "science",
- "maxLevel": 100,
- "experiencePerLevel": 1500,
- "defaultUnlocked": false,
- "requiredLevel": 8,
- "icon": "fa-microscope",
- "bonuses": { "criticalDamage": 0.1, "attack": 3 }
- },
- {
- "id": "bio_engineering",
- "name": "Bio-Engineering",
- "description": "Biological enhancements and healing",
- "category": "science",
- "maxLevel": 100,
- "experiencePerLevel": 1100,
- "defaultUnlocked": false,
- "requiredLevel": 6,
- "icon": "fa-dna",
- "bonuses": { "maxHealth": 15, "healthRegeneration": 0.05 }
- }
-]
diff --git a/GameServer/package.json b/GameServer/package.json
index 0e6623f..f8aa0b3 100644
--- a/GameServer/package.json
+++ b/GameServer/package.json
@@ -16,7 +16,8 @@
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
- "debug": "node --inspect server.js"
+ "debug": "node --inspect server.js",
+ "test": "node --experimental-vm-modules tests/run.js"
},
"dependencies": {
"compression": "^1.7.4",
@@ -36,4 +37,4 @@
"engines": {
"node": ">=18.0.0"
}
-}
+}
\ No newline at end of file
diff --git a/GameServer/server.js b/GameServer/server.js
index 2b8dee3..7252e0f 100644
--- a/GameServer/server.js
+++ b/GameServer/server.js
@@ -5,6 +5,7 @@
const express = require('express');
const http = require('http');
+const errorReporter = require('./utils/ErrorReporter');
const socketIo = require('socket.io');
const cors = require('cors');
const helmet = require('helmet');
@@ -144,6 +145,12 @@ app.use(cors({
credentials: true
}));
app.use(express.json({ limit: '10mb' }));
+app.use(errorReporter.requestMiddleware());
+
+// Health + metrics endpoint
+app.get('/health', (req, res) => {
+ res.json({ status: 'ok', ...errorReporter.getMetrics() });
+});
// Serve static files from the client directory
app.use(express.static(path.join(__dirname, '../Client')));
@@ -449,9 +456,33 @@ io.on('connection', (socket) => {
// Join server
playerData.joinServer(`devgame-server-${PORT}`);
- // Update last login time
+ // Update last login time + daily login streak gems (GDD §3 v3.2)
if (!playerData.stats) playerData.stats = {};
- playerData.stats.lastLogin = new Date().toISOString();
+ const now = new Date();
+ const lastLogin = playerData.stats.lastLogin ? new Date(playerData.stats.lastLogin) : null;
+ let streakGems = 0;
+ if (lastLogin) {
+ const hoursSince = (now - lastLogin) / 3600000;
+ if (hoursSince >= 20 && hoursSince <= 48) {
+ // Consecutive day login — increment streak
+ playerData.stats.loginStreak = Math.min(30, (playerData.stats.loginStreak || 0) + 1);
+ } else if (hoursSince > 48) {
+ // Streak broken
+ playerData.stats.loginStreak = 1;
+ }
+ } else {
+ playerData.stats.loginStreak = 1;
+ }
+ // Gem reward: day 1=0, day 3=1, day 7=3, day 14=5, day 30=10
+ const streak = playerData.stats.loginStreak || 1;
+ if (streak >= 30) streakGems = 10;
+ else if (streak >= 14) streakGems = 5;
+ else if (streak >= 7) streakGems = 3;
+ else if (streak >= 3) streakGems = 1;
+ if (streakGems > 0) {
+ playerData.stats.gems = (playerData.stats.gems || 0) + streakGems;
+ }
+ playerData.stats.lastLogin = now.toISOString();
// Ensure all required fields exist (for existing players)
if (playerData.stats.totalExperience === undefined) playerData.stats.totalExperience = playerData.stats.experience || 0;
@@ -499,7 +530,9 @@ io.on('connection', (socket) => {
...playerData.toObject(),
serverTimestamp: Date.now(),
serverTimezone: 'UTC'
- }
+ },
+ loginStreak: playerData.stats.loginStreak || 1,
+ streakGemsAwarded: streakGems || 0,
});
console.log(`[GAME SERVER] ${playerData.username} authenticated with Level ${playerData.stats.level}`);
@@ -894,54 +927,169 @@ io.on('connection', (socket) => {
}
});
- // ── CRAFTING: craft_item (GDD §11) ─────────────────────────────────────
+ // ── CRAFTING: craft_item (GDD §11) — timed queue ────────────────────────
+ // Materials are consumed immediately; item arrives after craft_time_seconds.
+ // Skill level reduces time: time = base * (1 - 0.01 * craftingLevel) capped at 50% reduction.
socket.on('craft_item', async ({ recipeId } = {}) => {
if (!socket.userId) return socket.emit('craft_result', { success: false, error: 'Not authenticated' });
- if (!recipeId) return socket.emit('craft_result', { success: false, error: 'No recipe specified' });
+ if (!recipeId) return socket.emit('craft_result', { success: false, error: 'No recipe specified' });
try {
const playerData = await PlayerData.findOne({ userId: socket.userId });
if (!playerData) return socket.emit('craft_result', { success: false, error: 'Player not found' });
- const result = craftingSystem.executeCraft(recipeId, playerData, socket.userId);
+ const recipe = craftingSystem.getRecipe(recipeId);
+ if (!recipe) return socket.emit('craft_result', { success: false, error: 'Recipe not found' });
- if (result.success) {
- playerData.markModified('inventory');
- playerData.markModified('crafting');
- await playerData.save();
+ // Check max queue size (5 simultaneous crafts)
+ const crafting = playerData.crafting || {};
+ const queue = Array.isArray(crafting.queue) ? crafting.queue : [];
+ if (queue.length >= 5)
+ return socket.emit('craft_result', { success: false, error: 'Crafting queue full (max 5)' });
- socket.emit('craft_result', {
- success: true,
- output: result.output,
- xpGained: result.xpGained,
- craftingLevel: result.craftingLevel,
- craftingXp: result.craftingXp,
- });
+ // Server-side material check
+ const check = craftingSystem.checkMaterials(recipeId, playerData.inventory || { items: [] });
+ if (!check.canCraft)
+ return socket.emit('craft_result', { success: false, error: 'Missing materials', missing: check.missing });
- // Emit updated inventory
- socket.emit('inventory_update', {
- items: playerData.inventory?.items || [],
- maxSize: playerData.inventory?.maxSize || 50,
- });
-
- console.log(`[CRAFTING] ${socket.username} crafted ${recipeId} — +${result.xpGained} XP`);
- } else {
- socket.emit('craft_result', result);
+ // Consume materials now
+ const inputs = recipe.recipe?.inputs || recipe.inputs || {};
+ const inv = playerData.inventory || { items: [] };
+ for (const [itemId, qty] of Object.entries(inputs)) {
+ craftingSystem._removeItems(inv, itemId, qty);
}
+ playerData.inventory = inv;
+
+ // Calculate craft time with skill reduction
+ const skillLevel = crafting.skill || 1;
+ const reduction = Math.min(0.5, skillLevel * 0.01); // 1% per level, cap 50%
+ const baseTimeSec = recipe.recipe?.craft_time_seconds
+ || recipe.recipe?.alloy_time_seconds
+ || recipe.recipe?.smelt_time_seconds
+ || recipe.recipe?.process_time_seconds
+ || recipe.recipe?.cook_time_seconds
+ || recipe.recipe?.harvest_time_seconds
+ || 30; // default 30s
+ const timeSec = Math.max(5, Math.round(baseTimeSec * (1 - reduction)));
+ const completesAt = Date.now() + timeSec * 1000;
+
+ // Queue the craft
+ const craftJobId = `craft_${Date.now()}_${Math.random().toString(36).slice(2,6)}`;
+ const outputs = recipe.recipe?.output || recipe.output || {};
+ queue.push({
+ jobId: craftJobId,
+ recipeId,
+ outputs,
+ xpGain: recipe.craft?.xp || recipe.xp || 10,
+ startedAt: Date.now(),
+ completesAt,
+ timeSec,
+ });
+
+ // Update skill XP on start (small preview XP — full XP on collect)
+ crafting.queue = queue;
+ crafting.skill = crafting.skill || 1;
+ crafting.experience = crafting.experience || 0;
+ playerData.crafting = crafting;
+
+ playerData.markModified('inventory');
+ playerData.markModified('crafting');
+ await playerData.save();
+
+ socket.emit('craft_result', {
+ success: true,
+ queued: true,
+ jobId: craftJobId,
+ recipeId,
+ timeSec,
+ completesAt,
+ queueLength: queue.length,
+ });
+ socket.emit('inventory_update', {
+ items: playerData.inventory?.items || [],
+ maxSize: playerData.inventory?.maxSize || 50,
+ });
+ socket.emit('craft_queue_update', { queue });
+ console.log(`[CRAFTING] ${socket.username} queued ${recipeId} — completes in ${timeSec}s`);
} catch (err) {
console.error('[CRAFTING] craft_item error:', err);
socket.emit('craft_result', { success: false, error: 'Server error' });
}
});
+ // ── CRAFTING: collect_craft — collect a completed craft job ─────────────
+ socket.on('collect_craft', async ({ jobId } = {}) => {
+ if (!socket.userId || !jobId) return;
+ try {
+ const playerData = await PlayerData.findOne({ userId: socket.userId });
+ if (!playerData) return;
+ const crafting = playerData.crafting || {};
+ const queue = Array.isArray(crafting.queue) ? crafting.queue : [];
+ const idx = queue.findIndex(j => j.jobId === jobId);
+ if (idx < 0) return socket.emit('collect_craft_result', { success: false, error: 'Job not found' });
+
+ const job = queue[idx];
+ if (Date.now() < job.completesAt)
+ return socket.emit('collect_craft_result', { success: false, error: 'Not ready yet', remainingMs: job.completesAt - Date.now() });
+
+ // Add outputs to inventory
+ const inv = playerData.inventory || { items: [] };
+ const outputItems = [];
+ for (const [itemId, qty] of Object.entries(job.outputs || {})) {
+ const item = { id: itemId, itemId, quantity: qty, obtainedAt: Date.now(), source: 'crafting' };
+ (inv.items || inv).push(item);
+ outputItems.push(item);
+ }
+ playerData.inventory = inv;
+
+ // Award XP and skill up
+ crafting.experience = (crafting.experience || 0) + job.xpGain;
+ const newSkill = Math.min(50, Math.floor(crafting.experience / 200) + 1);
+ crafting.skill = newSkill;
+ crafting.totalCrafted = (crafting.totalCrafted || 0) + 1;
+ queue.splice(idx, 1);
+ crafting.queue = queue;
+ playerData.crafting = crafting;
+
+ playerData.markModified('inventory');
+ playerData.markModified('crafting');
+ await playerData.save();
+
+ socket.emit('collect_craft_result', {
+ success: true, jobId, output: outputItems,
+ xpGained: job.xpGain, craftingLevel: newSkill,
+ craftingXp: crafting.experience,
+ });
+ socket.emit('inventory_update', { items: inv.items || [], maxSize: playerData.inventory?.maxSize || 50 });
+ socket.emit('craft_queue_update', { queue });
+ } catch (err) { socket.emit('collect_craft_result', { success: false, error: 'Server error' }); }
+ });
+
+ // ── CRAFTING: get_craft_queue — fetch current queue state ───────────────
+ socket.on('get_craft_queue', async () => {
+ if (!socket.userId) return;
+ try {
+ const playerData = await PlayerData.findOne({ userId: socket.userId });
+ if (!playerData) return;
+ const queue = Array.isArray(playerData.crafting?.queue) ? playerData.crafting.queue : [];
+ socket.emit('craft_queue_update', { queue, skill: playerData.crafting?.skill || 1, xp: playerData.crafting?.experience || 0 });
+ } catch (err) {}
+ });
+
// ── CRAFTING: check_craft (can player craft a recipe?) ──────────────────
socket.on('check_craft', async ({ recipeId } = {}) => {
if (!socket.userId || !recipeId) return;
try {
const playerData = await PlayerData.findOne({ userId: socket.userId });
if (!playerData) return;
+ const recipe = craftingSystem.getRecipe(recipeId);
const result = craftingSystem.checkMaterials(recipeId, playerData.inventory || { items: [] });
- socket.emit('craft_check_result', { recipeId, ...result });
+ const skillLevel = playerData.crafting?.skill || 1;
+ const reduction = Math.min(0.5, skillLevel * 0.01);
+ const baseTime = recipe?.recipe?.craft_time_seconds || recipe?.recipe?.alloy_time_seconds
+ || recipe?.recipe?.smelt_time_seconds || 30;
+ const timeSec = Math.max(5, Math.round(baseTime * (1 - reduction)));
+ socket.emit('craft_check_result', { recipeId, ...result, timeSec, skillLevel });
} catch (err) {
console.error('[CRAFTING] check_craft error:', err);
}
@@ -1198,18 +1346,35 @@ io.on('connection', (socket) => {
const client = connectedClients.get(socket.id);
const result = dungeonSystem.completeDungeon(instanceId);
- // Grant item rewards to player inventory/starbase
- if (result.success && result.rewards?.length && client?.userId) {
+ // Grant item rewards + gem bonuses to player inventory
+ if (result.success && client?.userId) {
try {
const playerData = await loadPlayerData(client.userId, client.username || 'Player');
if (playerData) {
- for (const reward of result.rewards) {
- const item = itemSystem.getItem(reward.itemId);
- if (!item) continue;
- itemSystem.applyPurchase(item, playerData, reward.quantity || 1);
+ // Grant item rewards
+ if (result.rewards?.length) {
+ for (const reward of result.rewards) {
+ const item = itemSystem.getItem(reward.itemId);
+ if (!item) continue;
+ itemSystem.applyPurchase(item, playerData, reward.quantity || 1);
+ }
}
+ // Gem rewards by dungeon difficulty (GDD §11 v3.2)
+ // extreme=1, legendary=3, boss kills add 1 bonus gem
+ const gemsByDifficulty = { tutorial:0, easy:0, medium:0, hard:0, extreme:1, legendary:3 };
+ const dungeon = dungeonSystem.getDungeon ? dungeonSystem.getDungeon(instanceId) : null;
+ const difficulty = dungeon?.difficulty || result.difficulty || 'medium';
+ const gemReward = gemsByDifficulty[difficulty] || 0;
+ if (gemReward > 0) {
+ playerData.stats.gems = (playerData.stats.gems || 0) + gemReward;
+ result.gemsAwarded = gemReward;
+ }
+
await savePlayerData(client.userId, playerData);
client.playerData = playerData;
+ if (gemReward > 0) {
+ socket.emit('economy_data', { credits: playerData.stats.credits, gems: playerData.stats.gems });
+ }
}
} catch (grantErr) {
console.error('[GAME SERVER] Failed to grant dungeon rewards:', grantErr.message);
@@ -1217,13 +1382,15 @@ io.on('connection', (socket) => {
}
// Log to combat log (GDD §9.5)
- socialSystem.addCombatLogEntry(playerData.userId, {
- type: 'dungeon', outcome: 'win',
- enemy: dungeon?.name || instanceId,
- xpGained: rewards?.experience || 0,
- timestamp: new Date()
- }).catch(()=>{});
- socket.emit('dungeon_completed', { rewards: result });
+ if (client?.playerData) {
+ socialSystem.addCombatLogEntry(client.playerData.userId, {
+ type: 'dungeon', outcome: 'win',
+ enemy: instanceId,
+ xpGained: result.xpReward || 0,
+ timestamp: new Date()
+ }).catch(()=>{});
+ }
+ socket.emit('dungeon_completed', { rewards: result });
} catch (error) {
console.error('[GAME SERVER] Error completing dungeon:', error);
socket.emit('dungeon_completed', { success: false, error: error.message });
@@ -1612,21 +1779,45 @@ io.on('connection', (socket) => {
const client = connectedClients.get(socket.id);
if (!client?.playerData) return;
const result = await marketSystem.buyListing(client.playerData, listingId);
- // Credit seller if online
+
+ // Credit seller — online: immediate push; offline: persist to DB so they receive on next login
+ let sellerCredited = false;
for (const [sid, cd] of connectedClients.entries()) {
if (cd.userId === result.listing.sellerId) {
cd.playerData.stats.credits = (cd.playerData.stats.credits||0) + result.proceeds;
io.to(sid).emit('economy_data',{credits:cd.playerData.stats.credits,gems:cd.playerData.stats.gems});
- io.to(sid).emit('market_sale', { listingId, amount: result.proceeds });
+ io.to(sid).emit('market_sale', { listingId, itemName: result.listing.itemName, amount: result.proceeds });
await savePlayerData(cd.userId, cd.playerData);
+ sellerCredited = true;
}
}
+ // Offline seller: load their data from DB, credit, and resave
+ if (!sellerCredited) {
+ try {
+ const PlayerData = require('./models/PlayerData');
+ const sellerDoc = await PlayerData.findOne({ userId: result.listing.sellerId });
+ if (sellerDoc) {
+ sellerDoc.stats.credits = (sellerDoc.stats.credits || 0) + result.proceeds;
+ await sellerDoc.save();
+ }
+ } catch(e) { console.warn('[market] offline seller credit error:', e.message); }
+ }
+
await savePlayerData(client.playerData.userId, client.playerData);
- socket.emit('buy_result',{success:true,listingId,proceeds:result.proceeds});
+ socket.emit('buy_result',{success:true,listingId,proceeds:result.proceeds,itemName:result.listing.itemName});
socket.emit('economy_data',{credits:client.playerData.stats.credits,gems:client.playerData.stats.gems});
} catch(err) { socket.emit('buy_result',{success:false,error:err.message}); }
});
+ // Price history for market sparklines (GDD §14 v3.2)
+ socket.on('get_price_history', async ({ itemId, days = 14 } = {}) => {
+ try {
+ if (!itemId) return socket.emit('price_history', { error: 'itemId required' });
+ const history = await marketSystem.getPriceHistory(itemId, Math.min(days, 30));
+ socket.emit('price_history', history);
+ } catch(err) { socket.emit('price_history', { error: err.message }); }
+ });
+
socket.on('cancel_listing', async ({ listingId }={}) => {
try {
const client = connectedClients.get(socket.id);
@@ -1710,6 +1901,100 @@ io.on('connection', (socket) => {
} catch(err) { socket.emit('alliance_warehouse_update',{success:false,error:err.message}); }
});
+ // Alliance Research Tree (GDD §12.3 — v3.2)
+ socket.on('get_alliance_research', async () => {
+ try {
+ const client = connectedClients.get(socket.id);
+ if (!client?.playerData?.allianceId) return socket.emit('alliance_research_data', { error: 'Not in an alliance' });
+ const Alliance = require('./systems/AllianceSystem').Alliance || mongoose.model('Alliance');
+ const alliance = await Alliance.findOne({ allianceId: client.playerData.allianceId });
+ if (!alliance) return socket.emit('alliance_research_data', { error: 'Alliance not found' });
+ const tree = require('./data/gso/alliance/research_tree.json');
+ socket.emit('alliance_research_data', {
+ tree,
+ completed: alliance.research?.completed || [],
+ inProgress: alliance.research?.inProgress || null,
+ });
+ } catch(err) { socket.emit('alliance_research_data', { error: err.message }); }
+ });
+
+ socket.on('start_alliance_research', async ({ techId } = {}) => {
+ try {
+ const client = connectedClients.get(socket.id);
+ if (!client?.playerData) return;
+ if (!client.playerData.allianceId) return socket.emit('alliance_research_result', { success:false, error:'Not in an alliance' });
+ if (!['founder','officer'].includes(client.playerData.allianceRank))
+ return socket.emit('alliance_research_result', { success:false, error:'Only founders and officers can start research' });
+
+ const Alliance = mongoose.model('Alliance');
+ const alliance = await Alliance.findOne({ allianceId: client.playerData.allianceId });
+ if (!alliance) return socket.emit('alliance_research_result', { success:false, error:'Alliance not found' });
+
+ const tree = require('./data/gso/alliance/research_tree.json');
+ const tech = tree.tiers.flatMap(t => t.techs).find(t => t.id === techId);
+ if (!tech) return socket.emit('alliance_research_result', { success:false, error:'Tech not found' });
+
+ const completed = alliance.research?.completed || [];
+ // Check prerequisites
+ for (const prereq of (tech.prereq || [])) {
+ if (!completed.includes(prereq))
+ return socket.emit('alliance_research_result', { success:false, error:`Requires ${prereq} first` });
+ }
+ if (completed.includes(techId))
+ return socket.emit('alliance_research_result', { success:false, error:'Already researched' });
+ if (alliance.research?.inProgress)
+ return socket.emit('alliance_research_result', { success:false, error:'Research already in progress' });
+
+ // Deduct cost from warehouse
+ const cost = tech.cost || {};
+ const wh = alliance.warehouse;
+ for (const [res, amt] of Object.entries(cost)) {
+ if (res === 'credits') {
+ if ((wh.credits||0) < amt) return socket.emit('alliance_research_result', {success:false, error:`Need ${amt} warehouse credits`});
+ wh.credits -= amt;
+ } else {
+ if ((wh[res]||0) < amt) return socket.emit('alliance_research_result', {success:false, error:`Need ${amt} warehouse ${res}`});
+ wh[res] -= amt;
+ }
+ }
+
+ const researchTimeSec = 3600; // 1 hour per tech (Phase 3 may vary)
+ alliance.research = {
+ ...(alliance.research||{}),
+ completed,
+ inProgress: { techId, startedAt: Date.now(), completesAt: Date.now() + researchTimeSec * 1000 },
+ };
+ alliance.markModified('research');
+ alliance.markModified('warehouse');
+ await alliance.save();
+
+ socket.emit('alliance_research_result', {
+ success: true, techId,
+ completesAt: alliance.research.inProgress.completesAt,
+ warehouse: alliance.warehouse,
+ });
+ } catch(err) { socket.emit('alliance_research_result', {success:false, error:err.message}); }
+ });
+
+ socket.on('collect_alliance_research', async () => {
+ try {
+ const client = connectedClients.get(socket.id);
+ if (!client?.playerData?.allianceId) return;
+ const Alliance = mongoose.model('Alliance');
+ const alliance = await Alliance.findOne({ allianceId: client.playerData.allianceId });
+ if (!alliance?.research?.inProgress) return socket.emit('alliance_research_result', {success:false, error:'No research in progress'});
+ if (Date.now() < alliance.research.inProgress.completesAt)
+ return socket.emit('alliance_research_result', {success:false, error:'Not complete yet', remainingMs: alliance.research.inProgress.completesAt - Date.now()});
+
+ const techId = alliance.research.inProgress.techId;
+ alliance.research.completed = [...(alliance.research.completed||[]), techId];
+ alliance.research.inProgress = null;
+ alliance.markModified('research');
+ await alliance.save();
+ socket.emit('alliance_research_result', { success:true, completed: techId, allCompleted: alliance.research.completed });
+ } catch(err) { socket.emit('alliance_research_result', {success:false, error:err.message}); }
+ });
+
// ════════════════════════════════════════════════════════════════════════
// FLEET MISSION HANDLERS (GDD §8.3)
// ════════════════════════════════════════════════════════════════════════
diff --git a/GameServer/socket/socketHandlers.js b/GameServer/socket/socketHandlers.js
deleted file mode 100644
index c4456ea..0000000
--- a/GameServer/socket/socketHandlers.js
+++ /dev/null
@@ -1,393 +0,0 @@
-/**
- * Socket Handlers - Manages real-time socket connections for game server
- */
-
-const jwt = require('jsonwebtoken');
-const logger = require('../utils/logger');
-const { getGameSystem } = require('../systems/GameSystem');
-
-class SocketHandlers {
- constructor(io, gameServers, connectedPlayers) {
- this.io = io;
- this.gameServers = gameServers;
- this.connectedPlayers = connectedPlayers; // Track actual player connections
- this.gameSystem = null;
-
- // Track connected users to prevent duplicate connections
- this.connectedUsers = new Map(); // userId -> socket.id
- this.userSockets = new Map(); // socket.id -> userId
-
- // Add connection cleanup interval
- this.startConnectionCleanup();
- }
-
- startConnectionCleanup() {
- // Clean up stale connections every 30 seconds
- setInterval(() => {
- this.cleanupStaleConnections();
- }, 30000);
- }
-
- cleanupStaleConnections() {
- logger.info(`[GAME SERVER] Checking ${this.connectedUsers.size} active connections...`);
- logger.info(`[GAME SERVER] Current tracked players: ${Array.from(this.connectedPlayers)}`);
-
- let playersRemoved = 0;
- for (const [userId, socketId] of this.connectedUsers.entries()) {
- const socket = this.io.sockets.sockets.get(socketId);
- if (!socket || !socket.connected) {
- logger.warn(`[GAME SERVER] Cleaning up stale connection for user ${userId} (socket: ${socketId})`);
- this.connectedUsers.delete(userId);
- this.userSockets.delete(socketId);
- if (this.connectedPlayers.has(userId)) {
- this.connectedPlayers.delete(userId);
- playersRemoved++;
- logger.info(`[GAME SERVER] Removed stale player ${userId}. Players removed: ${playersRemoved}`);
- }
- }
- }
-
- logger.info(`[GAME SERVER] Cleanup complete. Players removed: ${playersRemoved}, Total players now: ${this.connectedPlayers.size}`);
-
- // Update player count on API if players were removed
- if (playersRemoved > 0 && this.serverRegistration) {
- logger.info(`[GAME SERVER] Updating API player count after cleanup to: ${this.connectedPlayers.size}`);
- this.serverRegistration.updatePlayerCount(this.connectedPlayers.size);
- }
- }
-
- async initializeGameSystem() {
- const { initializeGameSystems } = require('../systems/GameSystem');
- this.gameSystem = await initializeGameSystems();
- }
-
- handleConnection(socket) {
- logger.info(`Game Server: Socket connected - ${socket.id}`);
-
- // Authentication middleware
- socket.use(async (packet, next) => {
- try {
- const token = socket.handshake.auth.token;
- if (!token) {
- return next(new Error('Authentication required'));
- }
-
- // Verify JWT token
- const decoded = jwt.verify(token, process.env.JWT_SECRET || 'fallback_secret');
- socket.userId = decoded.userId;
- socket.email = decoded.email;
-
- // Check if user is already connected from another client
- const existingSocketId = this.connectedUsers.get(decoded.userId);
- const wasAlreadyConnected = this.connectedPlayers.has(decoded.userId);
-
- logger.info(`[GAME SERVER] User ${decoded.userId} (${decoded.email}) connecting. Was already connected: ${wasAlreadyConnected}, Existing socket: ${existingSocketId}`);
-
- if (existingSocketId && existingSocketId !== socket.id) {
- logger.warn(`[GAME SERVER] User ${decoded.userId} attempting to connect from multiple clients. Disconnecting previous client.`);
- logger.warn(`[GAME SERVER] Existing socket: ${existingSocketId}, New socket: ${socket.id}`);
-
- // Disconnect the previous client
- const previousSocket = this.io.sockets.sockets.get(existingSocketId);
- if (previousSocket) {
- logger.info(`[GAME SERVER] Force disconnecting previous socket: ${existingSocketId}`);
- previousSocket.emit('force_disconnect', {
- reason: 'Another client connected with your account',
- newSocketId: socket.id
- });
- previousSocket.disconnect(true);
- } else {
- logger.warn(`[GAME SERVER] Previous socket ${existingSocketId} not found in active connections`);
- // Clean up the stale mapping
- this.connectedUsers.delete(decoded.userId);
- this.userSockets.delete(existingSocketId);
- if (!wasAlreadyConnected) {
- this.connectedPlayers.delete(decoded.userId);
- }
- }
- } else {
- logger.info(`[GAME SERVER] New connection for user ${decoded.userId} (socket: ${socket.id})`);
- }
-
- // Store user connection
- this.connectedUsers.set(decoded.userId, socket.id);
- this.userSockets.set(socket.id, decoded.userId);
-
- // Add to connected players tracking only if not already there
- const wasNotAlreadyConnected = !this.connectedPlayers.has(decoded.userId);
- this.connectedPlayers.add(decoded.userId);
-
- logger.info(`[GAME SERVER] User ${decoded.userId} added to tracking. Was not already connected: ${wasNotAlreadyConnected}, Total players: ${this.connectedPlayers.size}`);
-
- // Update player count on API only if this is a new unique user
- if (this.serverRegistration && wasNotAlreadyConnected) {
- logger.info(`[GAME SERVER] Updating API player count to: ${this.connectedPlayers.size}`);
- this.serverRegistration.updatePlayerCount(this.connectedPlayers.size);
- }
-
- next();
- } catch (error) {
- logger.error(`Socket authentication failed: ${error.message}`);
- socket.emit('authError', { error: 'Authentication failed' });
- socket.disconnect();
- }
- });
-
- // Event handlers
- socket.on('joinServer', (data) => this.handleJoinServer(socket, data));
- socket.on('leaveServer', (data) => this.handleLeaveServer(socket, data));
- socket.on('gameAction', (data) => this.handleGameAction(socket, data));
- socket.on('chatMessage', (data) => this.handleChatMessage(socket, data));
- socket.on('getPlayerList', (data) => this.handleGetPlayerList(socket, data));
- socket.on('disconnect', () => this.handleDisconnect(socket));
- }
-
- async handleJoinServer(socket, data) {
- try {
- const { serverId, userId, username } = data;
-
- // Verify user matches socket authentication
- if (socket.userId !== userId) {
- socket.emit('error', { message: 'User authentication mismatch' });
- return;
- }
-
- // Create or get game instance
- let gameInstance = this.gameSystem.getGameInstance(serverId);
- if (!gameInstance) {
- // This should ideally be handled by the API server
- // But for now, create a basic game instance
- gameInstance = this.gameSystem.createGameInstance({
- id: serverId,
- name: `Game ${serverId}`,
- type: 'public',
- region: 'us-east',
- maxPlayers: 10
- });
- }
-
- // Join player to game instance
- const playerData = {
- userId: userId,
- username: username,
- currentShip: data.currentShip,
- stats: data.stats
- };
-
- const joinedGame = this.gameSystem.joinGameInstance(socket, serverId, playerData);
-
- if (joinedGame) {
- // Notify player of successful join
- socket.emit('joinedServer', {
- serverId: serverId,
- gameInstance: {
- id: joinedGame.id,
- name: joinedGame.name
- }
- });
-
- // Notify other players
- socket.to(`game_${gameId}`).emit('playerJoined', {
- userId: socket.userId,
- username: socket.email || 'Player'
- });
-
- logger.info(`Player ${socket.userId} joined game ${gameId}`);
- } else {
- socket.emit('error', { message: 'Failed to join game' });
- }
- } catch (error) {
- logger.error(`Join game error: ${error.message}`);
- socket.emit('error', { message: 'Failed to join game' });
- }
- }
-
- async handleLeaveGame(socket, data) {
- try {
- const { gameId } = data;
-
- const leftGame = this.gameSystem.leaveGameInstance(socket, gameId);
-
- if (leftGame) {
- // Notify player of successful leave
- socket.emit('leftGame', { gameId: gameId });
-
- // Notify other players
- socket.to(`game_${gameId}`).emit('playerLeft', {
- userId: socket.userId,
- currentPlayers: leftGame.currentPlayers
- });
-
- logger.info(`Player left game ${gameId}`);
- } else {
- socket.emit('error', { message: 'Failed to leave game' });
- }
-
- } catch (error) {
- logger.error(`Leave game error: ${error.message}`);
- socket.emit('error', { message: 'Failed to leave game' });
- }
- }
-
- async handleGameAction(socket, data) {
- try {
- const { type, actionData } = data;
-
- // Handle game action through game system
- const success = this.gameSystem.handlePlayerAction(socket, type, actionData);
-
- if (!success) {
- socket.emit('error', { message: 'Failed to process game action' });
- }
-
- } catch (error) {
- logger.error(`Game action error: ${error.message}`);
- socket.emit('error', { message: 'Failed to process game action' });
- }
- }
-
- async handleChatMessage(socket, data) {
- try {
- const { message } = data;
-
- // Handle chat through game system
- const success = this.gameSystem.handlePlayerChat(socket, { message });
-
- if (!success) {
- socket.emit('error', { message: 'Failed to send chat message' });
- }
-
- } catch (error) {
- logger.error(`Chat message error: ${error.message}`);
- socket.emit('error', { message: 'Failed to send chat message' });
- }
- }
-
- async handleGetPlayerList(socket, data) {
- try {
- const { serverId } = data;
- this.sendPlayerList(socket, serverId);
- } catch (error) {
- logger.error(`Get player list error: ${error.message}`);
- socket.emit('error', { message: 'Failed to get player list' });
- }
- }
-
- async sendPlayerList(socket, serverId) {
- const gameInstance = this.gameSystem.getGameInstance(serverId);
-
- if (gameInstance) {
- const players = Array.from(gameInstance.players.values()).map(player => ({
- userId: player.userId,
- username: player.username,
- joinedAt: player.joinedAt,
- isReady: player.isReady,
- stats: player.stats
- }));
-
- socket.emit('playerList', {
- serverId: serverId,
- players: players,
- currentPlayers: gameInstance.currentPlayers,
- maxPlayers: gameInstance.maxPlayers
- });
- } else {
- socket.emit('error', { message: 'Game instance not found' });
- }
- }
-
- async handleDisconnect(socket) {
- try {
- logger.info(`Game Server: Socket disconnected - ${socket.id}`);
-
- // Get user ID from socket
- const userId = this.userSockets.get(socket.id);
- if (userId) {
- logger.info(`[GAME SERVER] User ${userId} disconnecting (socket: ${socket.id})`);
-
- // Remove from tracking maps
- this.connectedUsers.delete(userId);
- this.userSockets.delete(socket.id);
-
- // Remove from connected players tracking
- const wasTracked = this.connectedPlayers.has(userId);
- this.connectedPlayers.delete(userId);
-
- logger.info(`[GAME SERVER] User ${userId} removed from tracking. Was tracked: ${wasTracked}, Total players: ${this.connectedPlayers.size}`);
-
- // Update player count on API only if user was being tracked
- if (this.serverRegistration && wasTracked) {
- logger.info(`[GAME SERVER] Updating API player count to: ${this.connectedPlayers.size}`);
- this.serverRegistration.updatePlayerCount(this.connectedPlayers.size);
- }
-
- // Get player connection info
- const connection = this.gameSystem.getPlayerConnection(socket.id);
- if (connection && connection.gameId) {
- const gameId = connection.gameId;
-
- // Remove player from game
- const success = this.gameSystem.removePlayerFromGame(gameId, userId);
-
- if (success) {
- // Notify other players in the game
- const game = this.gameSystem.getGame(gameId);
- if (game) {
- this.io.to(gameId).emit('playerLeft', {
- userId,
- username: socket.email || 'Unknown',
- gameId,
- currentPlayers: game.currentPlayers
- });
- }
-
- logger.info(`Player ${userId} disconnected from game ${gameId}`);
- }
-
- if (success) {
- // Notify other players
- this.io.to(`game_${gameId}`).emit('playerLeft', {
- userId: socket.userId,
- currentPlayers: game.currentPlayers
- });
- logger.info(`Player ${socket.userId} disconnected from game ${gameId}`);
- }
- }
-
- logger.info(`[GAME SERVER] User ${userId} fully disconnected and cleaned up`);
- } else {
- logger.warn(`[GAME SERVER] Unknown socket ${socket.id} disconnected without user mapping`);
- }
- } catch (error) {
- logger.error(`[GAME SERVER] Disconnect error: ${error.message}`);
- }
- }
-
- // Server management methods
- getServerStatus() {
- const gameInstances = this.gameSystem.getAllGameInstances();
-
- return {
- activeServers: gameInstances.length,
- connectedPlayers: this.connectedPlayers.size,
- };
- }
-
- getConnectedUsers() {
- return Array.from(this.connectedUsers.keys());
- }
-
- getUserCount() {
- return this.connectedUsers.size;
- }
-
- broadcastToAll(event, data) {
- this.io.emit(event, data);
- }
-
- broadcastToServer(serverId, event, data) {
- this.io.to(`game_${serverId}`).emit(event, data);
- }
-}
-
-module.exports = SocketHandlers;
diff --git a/GameServer/systems/MarketSystem.js b/GameServer/systems/MarketSystem.js
index 8bb3509..9246015 100644
--- a/GameServer/systems/MarketSystem.js
+++ b/GameServer/systems/MarketSystem.js
@@ -3,6 +3,7 @@
* Types: Auction, Direct Sale
* 2% listing fee; 24/48/72-hour durations
* Tradeable: resources, modules, blueprints, consumables, cosmetics
+ * v3.2: Price history tracking — rolling 30-day window, per-item median/sparkline data
*/
const mongoose = require('mongoose');
@@ -12,7 +13,7 @@ const listingSchema = new mongoose.Schema({
sellerId: { type: String, required: true },
sellerName: { type: String, default: '' },
itemType: { type: String, required: true }, // 'resource'|'item'
- itemId: { type: String, required: true }, // resource key or item.id
+ itemId: { type: String, required: true },
itemName: { type: String, default: '' },
itemIcon: { type: String, default: '📦' },
quantity: { type: Number, default: 1 },
@@ -30,23 +31,105 @@ const listingSchema = new mongoose.Schema({
listingSchema.index({ isActive: 1, expiresAt: 1 });
listingSchema.index({ sellerId: 1 });
listingSchema.index({ itemId: 1, isActive: 1 });
+listingSchema.index({ itemId: 1, soldAt: -1 }); // for price history queries
const Listing = mongoose.model('MarketListing', listingSchema);
-const LISTING_FEE_PCT = 0.02; // 2% GDD §14.3
-const MAX_LISTINGS = 10; // per player (base)
+// ── Price History Schema (GDD §14 v3.2 extension) ─────────────────────────
+// Stores daily OHLC-style buckets per item for sparkline/median display
+const priceHistorySchema = new mongoose.Schema({
+ itemId: { type: String, required: true },
+ date: { type: String, required: true }, // 'YYYY-MM-DD'
+ open: { type: Number, default: 0 },
+ high: { type: Number, default: 0 },
+ low: { type: Number, default: 0 },
+ close: { type: Number, default: 0 },
+ volume: { type: Number, default: 0 }, // units sold
+ saleCount: { type: Number, default: 0 }, // number of transactions
+ sumPrice: { type: Number, default: 0 }, // for average calculation
+}, { timestamps: true });
+priceHistorySchema.index({ itemId: 1, date: -1 }, { unique: true });
+
+const PriceHistory = mongoose.model('MarketPriceHistory', priceHistorySchema);
+
+const LISTING_FEE_PCT = 0.02;
+const MAX_LISTINGS = 10;
const VALID_DURATIONS = [24, 48, 72];
+const HISTORY_DAYS = 30; // rolling window kept
const TRADEABLE_RESOURCES = {
- metal: { name:'Metal', icon:'⚙', minPrice:1, maxPrice:100 },
- gas: { name:'Gas', icon:'☁', minPrice:1, maxPrice:100 },
- crystal: { name:'Crystal', icon:'💎', minPrice:2, maxPrice:200 },
- energyCells: { name:'Energy Cells',icon:'⚡', minPrice:1, maxPrice:80 },
- darkMatter: { name:'Dark Matter', icon:'✦', minPrice:10, maxPrice:2000 },
+ metal: { name:'Metal', icon:'⚙', minPrice:1, maxPrice:100 },
+ gas: { name:'Gas', icon:'☁', minPrice:1, maxPrice:100 },
+ crystal: { name:'Crystal', icon:'💎', minPrice:2, maxPrice:200 },
+ energyCells: { name:'Energy Cells', icon:'⚡', minPrice:1, maxPrice:80 },
+ darkMatter: { name:'Dark Matter', icon:'✦', minPrice:10, maxPrice:2000 },
};
class MarketSystem {
- constructor() { this.Listing = Listing; }
+ constructor() {
+ this.Listing = Listing;
+ this.PriceHistory = PriceHistory;
+ }
+
+ // ── Internal: record a sale into price history buckets ──────────────────
+ async _recordSale(itemId, pricePerUnit, quantity) {
+ try {
+ const date = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
+ const existing = await PriceHistory.findOne({ itemId, date });
+ if (existing) {
+ existing.high = Math.max(existing.high, pricePerUnit);
+ existing.low = existing.low > 0 ? Math.min(existing.low, pricePerUnit) : pricePerUnit;
+ existing.close = pricePerUnit;
+ existing.volume += quantity;
+ existing.saleCount += 1;
+ existing.sumPrice += pricePerUnit * quantity;
+ await existing.save();
+ } else {
+ await PriceHistory.create({
+ itemId, date,
+ open: pricePerUnit, high: pricePerUnit, low: pricePerUnit, close: pricePerUnit,
+ volume: quantity, saleCount: 1, sumPrice: pricePerUnit * quantity,
+ });
+ }
+ // Prune old records beyond HISTORY_DAYS
+ const cutoff = new Date();
+ cutoff.setDate(cutoff.getDate() - HISTORY_DAYS);
+ const cutoffStr = cutoff.toISOString().slice(0, 10);
+ await PriceHistory.deleteMany({ itemId, date: { $lt: cutoffStr } });
+ } catch (e) {
+ console.warn('[MarketSystem] _recordSale error (non-fatal):', e.message);
+ }
+ }
+
+ // ── Public: get price history for an item (last N days) ─────────────────
+ async getPriceHistory(itemId, days = 14) {
+ const cutoff = new Date();
+ cutoff.setDate(cutoff.getDate() - days);
+ const cutoffStr = cutoff.toISOString().slice(0, 10);
+ const rows = await PriceHistory.find({ itemId, date: { $gte: cutoffStr } })
+ .sort({ date: 1 }).lean();
+
+ const median = rows.length > 0
+ ? rows.reduce((s, r) => s + (r.sumPrice / Math.max(r.volume, 1)), 0) / rows.length
+ : null;
+
+ return {
+ itemId,
+ days: rows.map(r => ({
+ date: r.date,
+ open: r.open,
+ high: r.high,
+ low: r.low,
+ close: r.close,
+ volume: r.volume,
+ saleCount: r.saleCount,
+ avg: r.volume > 0 ? Math.round(r.sumPrice / r.volume) : r.close,
+ })),
+ median: median !== null ? Math.round(median) : null,
+ allTimeMin: rows.length ? Math.min(...rows.map(r => r.low)) : null,
+ allTimeMax: rows.length ? Math.max(...rows.map(r => r.high)) : null,
+ };
+ }
/** List a resource on the market */
async listResource(playerData, { resource, quantity, pricePerUnit, durationHours = 24 }) {
@@ -55,23 +138,19 @@ class MarketSystem {
pricePerUnit = Math.floor(pricePerUnit);
durationHours = VALID_DURATIONS.includes(durationHours) ? durationHours : 24;
- if (quantity < 1) throw new Error('Quantity must be ≥ 1');
- if (pricePerUnit < 1) throw new Error('Price must be ≥ 1 credit');
+ if (quantity < 1) throw new Error('Quantity must be ≥ 1');
+ if (pricePerUnit < 1) throw new Error('Price must be ≥ 1 credit');
- // Check median manipulation (stub — skip if no data)
const res = playerData.resources || {};
- if ((res[resource] || 0) < quantity) throw new Error(`Insufficient ${resource}: have ${res[resource]||0}, need ${quantity}`);
+ if ((res[resource] || 0) < quantity)
+ throw new Error(`Insufficient ${resource}: have ${res[resource]||0}, need ${quantity}`);
- // Count existing listings
const myListings = await Listing.countDocuments({ sellerId: playerData.userId, isActive: true });
if (myListings >= MAX_LISTINGS) throw new Error(`Max ${MAX_LISTINGS} active listings`);
- // Deduct resources
res[resource] -= quantity;
-
- // Listing fee in credits (2%)
- const totalPrice = pricePerUnit * quantity;
- const listingFee = Math.ceil(totalPrice * LISTING_FEE_PCT);
+ const totalPrice = pricePerUnit * quantity;
+ const listingFee = Math.ceil(totalPrice * LISTING_FEE_PCT);
if ((playerData.stats?.credits || 0) < listingFee) throw new Error(`Listing fee: ${listingFee} credits`);
playerData.stats.credits -= listingFee;
@@ -84,9 +163,7 @@ class MarketSystem {
itemId: resource,
itemName: cfg.name,
itemIcon: cfg.icon,
- quantity,
- pricePerUnit,
- totalPrice,
+ quantity, pricePerUnit, totalPrice,
currency: 'credits',
expiresAt: new Date(Date.now() + durationHours * 3600 * 1000),
durationHours,
@@ -97,11 +174,12 @@ class MarketSystem {
/** List an inventory item */
async listItem(playerData, { itemId, pricePerUnit, durationHours = 24 }) {
- const inventory = playerData.inventory || [];
- const idx = inventory.findIndex(i => i.id === itemId);
+ const inventory = playerData.inventory?.items || playerData.inventory || [];
+ const idx = inventory.findIndex(i => i && i.id === itemId);
if (idx < 0) throw new Error('Item not found in inventory');
const item = inventory[idx];
- if (item.type === 'ship' && item.id === playerData.stats?.activeShipId) throw new Error('Cannot list your active ship');
+ if (item.type === 'ship' && item.id === playerData.stats?.activeShipId)
+ throw new Error('Cannot list your active ship');
pricePerUnit = Math.floor(pricePerUnit);
durationHours = VALID_DURATIONS.includes(durationHours) ? durationHours : 24;
@@ -115,42 +193,44 @@ class MarketSystem {
inventory.splice(idx, 1);
const listing = new Listing({
- listingId: 'listing_' + Date.now() + '_' + Math.random().toString(36).slice(2, 6),
- sellerId: playerData.userId,
- sellerName: playerData.username,
- itemType: 'item',
- itemId: item.id,
- itemName: item.name || item.id,
- itemIcon: item.icon || '📦',
- quantity: 1,
+ listingId: 'listing_' + Date.now() + '_' + Math.random().toString(36).slice(2, 6),
+ sellerId: playerData.userId,
+ sellerName: playerData.username,
+ itemType: 'item',
+ itemId: item.id,
+ itemName: item.name || item.id,
+ itemIcon: item.icon || '📦',
+ quantity: 1,
pricePerUnit,
- totalPrice: pricePerUnit,
- currency: 'credits',
- expiresAt: new Date(Date.now() + durationHours * 3600 * 1000),
+ totalPrice: pricePerUnit,
+ currency: 'credits',
+ expiresAt: new Date(Date.now() + durationHours * 3600 * 1000),
durationHours,
- _itemData: JSON.stringify(item),
+ _itemData: JSON.stringify(item),
});
await listing.save();
return { listing, listingFee };
}
- /** Buy a listing */
+ /** Buy a listing — records price history on sale */
async buyListing(buyerData, listingId) {
const listing = await Listing.findOne({ listingId, isActive: true });
- if (!listing) throw new Error('Listing not found or already sold');
- if (listing.expiresAt < new Date()) throw new Error('Listing expired');
- if (listing.sellerId === buyerData.userId) throw new Error('Cannot buy your own listing');
- if ((buyerData.stats?.credits || 0) < listing.totalPrice) throw new Error(`Need ${listing.totalPrice} credits, have ${buyerData.stats?.credits||0}`);
+ if (!listing) throw new Error('Listing not found or already sold');
+ if (listing.expiresAt < new Date()) throw new Error('Listing expired');
+ if (listing.sellerId === buyerData.userId) throw new Error('Cannot buy your own listing');
+ if ((buyerData.stats?.credits || 0) < listing.totalPrice)
+ throw new Error(`Need ${listing.totalPrice} credits, have ${buyerData.stats?.credits||0}`);
buyerData.stats.credits -= listing.totalPrice;
- // Transfer goods to buyer
if (listing.itemType === 'resource') {
if (!buyerData.resources) buyerData.resources = {};
buyerData.resources[listing.itemId] = (buyerData.resources[listing.itemId] || 0) + listing.quantity;
} else {
- if (!buyerData.inventory) buyerData.inventory = [];
- try { buyerData.inventory.push(JSON.parse(listing._itemData)); } catch(e) { /* fallback */ }
+ const inv = buyerData.inventory?.items || buyerData.inventory;
+ if (Array.isArray(inv)) {
+ try { inv.push(JSON.parse(listing._itemData)); } catch(e) {}
+ }
}
listing.isActive = false;
@@ -158,33 +238,35 @@ class MarketSystem {
listing.soldAt = new Date();
await listing.save();
- // Return sale proceeds to seller (handled async — seller gets credits on next login or via event)
+ // Record the sale in price history (non-blocking)
+ this._recordSale(listing.itemId, listing.pricePerUnit, listing.quantity);
+
return { listing, proceeds: listing.totalPrice };
}
- /** Cancel own listing — returns resources/item minus fee (no fee refund per GDD) */
+ /** Cancel own listing */
async cancelListing(playerData, listingId) {
const listing = await Listing.findOne({ listingId, sellerId: playerData.userId, isActive: true });
if (!listing) throw new Error('Listing not found');
-
listing.isActive = false;
await listing.save();
- // Return goods
if (listing.itemType === 'resource') {
if (!playerData.resources) playerData.resources = {};
playerData.resources[listing.itemId] = (playerData.resources[listing.itemId] || 0) + listing.quantity;
} else {
- if (!playerData.inventory) playerData.inventory = [];
- try { playerData.inventory.push(JSON.parse(listing._itemData)); } catch(e) { /* skip */ }
+ const inv = playerData.inventory?.items || playerData.inventory;
+ if (Array.isArray(inv)) {
+ try { inv.push(JSON.parse(listing._itemData)); } catch(e) {}
+ }
}
return listing;
}
async getListings({ itemId, category, limit = 40 } = {}) {
const filter = { isActive: true, expiresAt: { $gt: new Date() } };
- if (itemId) filter.itemId = itemId;
- if (category) filter.itemType = category;
+ if (itemId) filter.itemId = itemId;
+ if (category) filter.itemType = category;
return Listing.find(filter).sort({ pricePerUnit: 1 }).limit(limit).lean();
}
@@ -195,12 +277,14 @@ class MarketSystem {
async expireListings() {
const now = new Date();
const expired = await Listing.find({ isActive: true, expiresAt: { $lt: now } });
- // TODO: return resources to sellers (deferred — done on next login)
- await Listing.updateMany({ isActive: true, expiresAt: { $lt: now } }, { $set: { isActive: false } });
+ await Listing.updateMany(
+ { isActive: true, expiresAt: { $lt: now } },
+ { $set: { isActive: false } }
+ );
return expired.length;
}
getTradeableResources() { return TRADEABLE_RESOURCES; }
}
-module.exports = { MarketSystem, Listing };
+module.exports = { MarketSystem, Listing, PriceHistory };
diff --git a/GameServer/tests/run.js b/GameServer/tests/run.js
new file mode 100644
index 0000000..02bbf1c
--- /dev/null
+++ b/GameServer/tests/run.js
@@ -0,0 +1,140 @@
+/**
+ * GSO Test Runner (no external dependencies)
+ * Run: node tests/run.js
+ */
+
+// Mock mongoose so MarketSystem can be required without a live DB
+const Module = require('module');
+const origLoad = Module._load;
+Module._load = function(name, ...args) {
+ if (name === 'mongoose') {
+ const fakeSchema = function(def) { this.def = def; };
+ fakeSchema.prototype.index = function() {};
+ fakeSchema.Types = { Mixed: 'Mixed' };
+ return { Schema: fakeSchema, model: () => class {} };
+ }
+ return origLoad.call(this, name, ...args);
+};
+
+let passed = 0, failed = 0;
+function test(name, fn) {
+ try { fn(); console.log(` ✅ ${name}`); passed++; }
+ catch(e) { console.log(` ❌ ${name}\n ${e.message}`); failed++; }
+}
+function expect(val) {
+ return {
+ toBe: (x) => { if (val !== x) throw new Error(`Expected ${JSON.stringify(x)}, got ${JSON.stringify(val)}`); },
+ toBeTruthy: () => { if (!val) throw new Error(`Expected truthy, got ${val}`); },
+ toBeGreaterThan:(x) => { if (!(val > x)) throw new Error(`Expected > ${x}, got ${val}`); },
+ toBeLessThan: (x) => { if (!(val < x)) throw new Error(`Expected < ${x}, got ${val}`); },
+ };
+}
+
+// ─── CraftingSystem ──────────────────────────────────────────────────────────
+console.log('\n📦 CraftingSystem');
+const CraftingSystem = require('../systems/CraftingSystem');
+const mockLoader = {
+ getRecipe: (id) => id === 'test_recipe' ? {
+ recipe: { inputs: { iron_ore: 2 }, output: { iron_ingot: 1 }, craft_time_seconds: 30 },
+ craft: { xp: 10 }
+ } : null,
+ getAllRecipes: () => [], getRecipesByType: () => [], getCraftingTabs: () => [],
+};
+const cs = new CraftingSystem(mockLoader);
+
+test('canCraft with sufficient items', () => {
+ const r = cs.checkMaterials('test_recipe', { items: [{id:'iron_ore', quantity:3}] });
+ if (!r.canCraft) throw new Error('Expected canCraft=true');
+});
+test('fails with insufficient items', () => {
+ const r = cs.checkMaterials('test_recipe', { items: [{id:'iron_ore', quantity:1}] });
+ if (r.canCraft) throw new Error('Expected canCraft=false');
+ if (r.missing[0].need !== 2) throw new Error(`Expected need=2, got ${r.missing[0].need}`);
+});
+test('unknown recipe -> canCraft=false', () => {
+ const r = cs.checkMaterials('nope', { items: [] });
+ if (r.canCraft) throw new Error('Should be false');
+});
+test('_calcSkillLevel: 0 XP = level 1', () => expect(cs._calcSkillLevel(0)).toBe(1));
+test('_calcSkillLevel: 200 XP = level 2', () => expect(cs._calcSkillLevel(200)).toBe(2));
+test('_calcSkillLevel: caps at 50', () => expect(cs._calcSkillLevel(99999)).toBe(50));
+test('_removeItems: reduces quantity', () => {
+ const inv = { items: [{id:'iron_ore', quantity:5}] };
+ cs._removeItems(inv, 'iron_ore', 3);
+ expect(inv.items[0].quantity).toBe(2);
+});
+test('_removeItems: removes item fully', () => {
+ const inv = { items: [{id:'iron_ore', quantity:2}] };
+ cs._removeItems(inv, 'iron_ore', 2);
+ expect(inv.items.length).toBe(0);
+});
+
+// ─── MarketSystem ────────────────────────────────────────────────────────────
+console.log('\n💰 MarketSystem');
+const { MarketSystem } = require('../systems/MarketSystem');
+const ms = new MarketSystem();
+test('has 5 tradeable resources', () => expect(Object.keys(ms.getTradeableResources()).length).toBe(5));
+test('darkMatter minPrice = 10', () => expect(ms.getTradeableResources().darkMatter.minPrice).toBe(10));
+test('metal maxPrice = 100', () => expect(ms.getTradeableResources().metal.maxPrice).toBe(100));
+
+// ─── XP Progression ──────────────────────────────────────────────────────────
+console.log('\n⭐ XP Progression (GDD §3.2: 500 × L^1.65)');
+const xpReq = (L) => Math.round(500 * Math.pow(L, 1.65));
+test('Level 1 = 500 XP', () => expect(xpReq(1)).toBe(500));
+test('Level 5 > Level 2', () => expect(xpReq(5)).toBeGreaterThan(xpReq(2)));
+test('Level 10 > 10,000', () => expect(xpReq(10)).toBeGreaterThan(10000));
+test('Level 50 > 300,000', () => expect(xpReq(50)).toBeGreaterThan(300000));
+
+// ─── Alliance Research Tree ───────────────────────────────────────────────────
+console.log('\n🛡 Alliance Research Tree');
+const tree = require('../data/gso/alliance/research_tree.json');
+test('3 tiers', () => expect(tree.tiers.length).toBe(3));
+test('Tier 1 has 3 techs', () => expect(tree.tiers[0].techs.length).toBe(3));
+test('Tier 2 has prerequisites', () => {
+ const ok = tree.tiers[1].techs.some(t => t.prereq?.length > 0);
+ if (!ok) throw new Error('No tier 2 tech has prerequisites');
+});
+test('All techs have id/name/cost/effect', () => {
+ for (const tier of tree.tiers)
+ for (const t of tier.techs)
+ if (!t.id||!t.name||!t.cost||!t.effect)
+ throw new Error(`Tech missing fields: ${JSON.stringify(t)}`);
+});
+
+// ─── Locales ──────────────────────────────────────────────────────────────────
+console.log('\n🌍 Locales');
+const fs2 = require('fs'), path2 = require('path');
+for (const lang of ['en','de','fr','es','ja','zh','ko','pt']) {
+ test(`${lang}.json has nav/resources/actions`, () => {
+ const locPath = path2.join(__dirname,'../../Client/locales',`${lang}.json`);
+ const loc = JSON.parse(fs2.readFileSync(locPath,'utf8'));
+ if (!loc.nav?.dashboard) throw new Error('Missing nav.dashboard');
+ if (!loc.resources?.metal) throw new Error('Missing resources.metal');
+ if (!loc.actions?.build) throw new Error('Missing actions.build');
+ });
+}
+
+// ─── Recipe time keys ─────────────────────────────────────────────────────────
+console.log('\n⏱ Recipe Time Coverage');
+const TIME_KEYS = ['craft_time_seconds','alloy_time_seconds','smelt_time_seconds','process_time_seconds','cook_time_seconds','harvest_time_seconds'];
+
+test('alloy recipes have alloy_time_seconds', () => {
+ const dir = path2.join(__dirname,'../data/gso/recipes/alloys');
+ for (const f of fs2.readdirSync(dir).filter(f=>f.endsWith('.json'))) {
+ const rec = JSON.parse(fs2.readFileSync(path2.join(dir,f)));
+ if (!TIME_KEYS.some(k=>rec.recipe?.[k]!==undefined)) throw new Error(`${f} missing time key`);
+ }
+});
+test('smelting recipes have smelt_time_seconds', () => {
+ const dir = path2.join(__dirname,'../data/gso/recipes/smelting');
+ for (const f of fs2.readdirSync(dir).filter(f=>f.endsWith('.json'))) {
+ const rec = JSON.parse(fs2.readFileSync(path2.join(dir,f)));
+ if (!rec.recipe?.smelt_time_seconds) throw new Error(`${f} missing smelt_time_seconds`);
+ }
+});
+
+// ─── Summary ──────────────────────────────────────────────────────────────────
+console.log(`\n${'─'.repeat(50)}`);
+console.log(`Results: ${passed} passed, ${failed} failed`);
+if (failed > 0) { console.log('❌ Some tests failed'); process.exit(1); }
+else console.log('✅ All tests passed');
diff --git a/GameServer/utils/ErrorReporter.js b/GameServer/utils/ErrorReporter.js
new file mode 100644
index 0000000..048d491
--- /dev/null
+++ b/GameServer/utils/ErrorReporter.js
@@ -0,0 +1,119 @@
+/**
+ * GSO Error Reporter & Analytics (GDD Phase 3 — v3.2 lightweight implementation)
+ * Logs structured errors to file + provides in-memory analytics counters.
+ * Can be wired to external services (Sentry, Datadog) by replacing _sendToExternal().
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+class ErrorReporter {
+ constructor(options = {}) {
+ this.logDir = options.logDir || path.join(__dirname, '../logs');
+ this.service = options.service || 'GameServer';
+ this.env = process.env.NODE_ENV || 'development';
+ this.counters = {}; // event_type → count
+ this.errors = []; // last 100 errors in memory
+ this.maxErrors = 100;
+
+ // Ensure logs directory exists
+ if (!fs.existsSync(this.logDir)) {
+ fs.mkdirSync(this.logDir, { recursive: true });
+ }
+ }
+
+ // ── Error capture ──────────────────────────────────────────────────────────
+ captureError(err, context = {}) {
+ const entry = {
+ ts: new Date().toISOString(),
+ service: this.service,
+ env: this.env,
+ message: err?.message || String(err),
+ stack: err?.stack || null,
+ context,
+ };
+
+ // Store in memory ring buffer
+ this.errors.push(entry);
+ if (this.errors.length > this.maxErrors) this.errors.shift();
+
+ // Write to daily log file (non-blocking)
+ const logFile = path.join(this.logDir, `errors-${new Date().toISOString().slice(0,10)}.log`);
+ const line = JSON.stringify(entry) + '\n';
+ fs.appendFile(logFile, line, () => {}); // fire-and-forget
+
+ // Increment counter
+ this.increment('errors.total');
+
+ // Hook for external service (Sentry, etc.)
+ this._sendToExternal(entry);
+
+ return entry;
+ }
+
+ // ── Analytics event tracking ───────────────────────────────────────────────
+ track(event, data = {}) {
+ this.increment(event);
+ if (this.env === 'development') {
+ const logFile = path.join(this.logDir, `analytics-${new Date().toISOString().slice(0,10)}.log`);
+ fs.appendFile(logFile, JSON.stringify({ ts: new Date().toISOString(), event, data }) + '\n', () => {});
+ }
+ }
+
+ increment(key) {
+ this.counters[key] = (this.counters[key] || 0) + 1;
+ }
+
+ // ── Metrics snapshot ───────────────────────────────────────────────────────
+ getMetrics() {
+ return {
+ service: this.service,
+ uptime: Math.round(process.uptime()),
+ memoryMB: Math.round(process.memoryUsage().heapUsed / 1048576),
+ counters: { ...this.counters },
+ recentErrors: this.errors.slice(-10).map(e => ({ ts: e.ts, message: e.message, context: e.context })),
+ };
+ }
+
+ // ── Express middleware ─────────────────────────────────────────────────────
+ requestMiddleware() {
+ return (req, res, next) => {
+ const start = Date.now();
+ this.increment('http.requests');
+ res.on('finish', () => {
+ const ms = Date.now() - start;
+ this.increment(`http.${res.statusCode >= 400 ? 'errors' : 'success'}`);
+ if (ms > 2000) this.track('http.slow_request', { path: req.path, ms });
+ });
+ next();
+ };
+ }
+
+ errorMiddleware() {
+ return (err, req, res, next) => {
+ this.captureError(err, { path: req.path, method: req.method });
+ res.status(500).json({ error: 'Internal server error' });
+ };
+ }
+
+ // ── Socket.IO event tracking helper ───────────────────────────────────────
+ trackSocketEvent(eventName, userId) {
+ this.increment(`socket.${eventName}`);
+ this.increment('socket.total');
+ }
+
+ // ── External service stub ──────────────────────────────────────────────────
+ _sendToExternal(entry) {
+ // Replace with: Sentry.captureException(new Error(entry.message))
+ // or: axios.post(process.env.ERROR_WEBHOOK_URL, entry)
+ // Currently: no-op in development; log to console in production
+ if (this.env === 'production') {
+ console.error('[ErrorReporter]', entry.message, entry.context);
+ }
+ }
+}
+
+// Singleton
+const reporter = new ErrorReporter({ service: 'GameServer' });
+
+module.exports = reporter;
👥 Social
+ +🤝 Add Friend
-📬 Friend Requests (0)
-🤝 Add Friend
+ +📬 Friend Requests (0)
+ +👾 Friends (0 online)
++ 🌐 Faction Reputation (GDD §15.3) + +
++ ⚔ Combat Log (GDD §9.5) + +
+