Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

Помогите Подключение лаунчера к MySql

Тема в разделе "[Архив] Помощь", создана пользователем iZuk, 1 мар 2013.

  1. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    Собственно дело вот в чём:
    лаунчер от maximusorg (пробовал и другие), подключается к базе mysql (это видно, если поменять в веб части допустим пароль к базе, то лаунчер не грузит ни новости ни мониторинг), запускается клиент, но во время подключения к серверу выдает ошибку: "Запрос к базе завершился ошибкой"
    пробовал базы db4free, hostinger, а также платную на sprinthost везде одно и тоже.
    Прошу помощи, кто сталкивался с этим?

    Дополню:
    В mysql таблица accounts, в ней поля (которые имеют отношение к делу по моему мнению) - id, login, server.
    Мб стоит поменять checkserver.php? Его код ниже.

    Код:
    <?php
    define('INCLUDE_CHECK',true);
    include ("bd_con.php");
    $user = mysql_real_escape_string($_GET['user]);
    $serverid = mysql_real_escape_string($_GET['serverid']);
    $result = mysql_query("Select $db_columnUser From $db_table Where $db_columnUser='$user' And $db_columnServer='$serverid'") or die ("Запрос к базе завершился ошибкой.");
    if(mysql_num_rows($result) == 1){ echo "YES"; } else { echo "NO"; }
    ?>

    include ("bd_con.php"); тут изначально было connect.php, но в исходниках был файл с таким названием подключающийся к mysql

    Поставил другой checkserver.php, теперь ошибка "NO"
    Если поменять в коде расположенном ниже "NO" на "ФРАЗА", то и ошибка будет "ФРАЗА", т.е. не находит пользователя, хотя пользователи в базе есть.
    Код:
              $str = "Server Test [User not found] User [$user] Server ID [$serverid]";
              echo "NO";
    код:

    Код:
    <?php
    require_once('../system.php');
    $str = '';
     
    if (!empty($_GET['user']) and !empty($_GET['serverId'])) {
     
        $user        = $_GET['user'];
        $serverid    = $_GET['serverId'];
     
        if (!preg_match("/^[a-zA-Z0-9_-]+$/", $user)) {
       
                    $str = "Server Test [Bad symbols Login] ";
                    echo "NO";
       
        } elseif (!preg_match("/^[a-z0-9_-]+$/", $serverid)) {
       
                    $str = "Server Test [Bad symbols ServerId] ";
                    echo "NO";
               
        } else {
       
            $result = BD("SELECT $bd_aUsername FROM $bd_table_accounts WHERE $bd_aUsername='".SQLComp($user)."' AND $bd_aServer='".SQLComp($serverid)."'");
     
            if(mysql_num_rows($result) == 1){
       
              $user_login = new User($user,$bd_aUsername);
              $user_login->gameLoginConfirm();
         
              $str = "Server Test [Success]";
              echo "YES";
         
            } else {
       
              $str = "Server Test [User not found] User [$user] Server ID [$serverid]";
              echo "NO";
                     
            }
       
        }
     
    } else {
     
        $str = "Server Test [GET parameter empty] ";
        if (empty($_GET['user'])) $str .= "USER parameter is empty | ";
        if (empty($_GET['serverId'])) $str .= "SERVERID parameter is empty";
     
        echo "NO";
     
    }
     
    vtxtlog($str);
    ?>
     
  2. Хостинг MineCraft
    <
  3. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    Если переименовать строчку в таблице accounts с "login" на "name", но НЕ МЕНЯЯ в bd_con.php, то в ЛАУНЧЕРЕ, а не в клиенте игры не находит аккаунт
    если же поменять в bd_con.php, ошибка выдается в клиенте при подключении к серверу.
    Т.Е. если я правильно понимаю, лаунчер отлично подключается к базе. Не подключается сам сервер? Если я прав, то как вообще сервер на mcpc+ подключить к mysql и "дать" ему понять где "лежат" пользователи?
     
  4. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    "Запрос к базе завершился ошибкой" ищи ошибки в именах таблиц или колонок или их отсутствие.
     
  5. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    ну это я уже понял, только я в этом совсем не шарю, буквально второй день занимаюсь. Коды выложил, сейчас выложу код system.php (я так понял все ниточки ведут к ней)
    Код system.php :
    Код:
    <?php
    require_once('bd_con.php');
    require_once('mod_config.php');
     
    /*
     
    Файл - system.php
     
    Системные функции - генерация пароля, проверка пароля и др.
     
    Класс пользователя сайта, авторизация пользователя
     
    */
     
    Class User {
    var $id;
    var $name;
    var $lvl;
    var $tmp;
    var $ip;
    var $email;
     
        function User($input,$method) {
        global $bd_table_accounts,$bd_aUsername,$bd_aUserID,$bd_aLvl,$bd_aTmp,$bd_aIP;
             
                $result = BD("SELECT $bd_aUsername,$bd_aUserID,$bd_aLvl,$bd_aTmp,$bd_aIP,email FROM $bd_table_accounts WHERE ".SQLComp($method)."='".SQLComp($input)."'");
             
                if ( !$result or !mysql_num_rows( $result ) ) $this->id=false;
                else {
             
                $line = mysql_fetch_array($result, MYSQL_ASSOC);
             
                $this->id = $line[$bd_aUserID];         
                $this->name = $line[$bd_aUsername];         
                $this->lvl = $line[$bd_aLvl];
                $this->tmp = $line[$bd_aTmp];
                $this->ip = $line[$bd_aIP];
                $this->email = $line['email'];
             
                }
                return true;         
        }
     
        function canPostComment() {
     
            $result = BD("SELECT id FROM comments WHERE user_id='".$this->id."' AND time>NOW()-INTERVAL 1 MINUTE");
            if ( mysql_num_rows( $result ) ) return false; 
         
            return true;
     
        }
     
        function gameLoginConfirm() {
        global $bd_table_accounts,$bd_aUserID,$bd_aServer;
     
            if (!$this->id) return false;
     
            BD("UPDATE $bd_table_accounts SET gameplay_last=NOW() WHERE $bd_aUserID='".$this->id."'");
         
            return true;
        }
     
        function gameLogoutConfirm() {
        global $bd_table_accounts,$bd_aUserID,$bd_aServer;
     
            if (!$this->id) return false;
     
            $result = BD("SELECT $bd_aUserID FROM $bd_table_accounts WHERE $bd_aServer IS NOT NULL and $bd_aUserID='".$this->id."'");
         
            if (mysql_num_rows( $result ) == 1)
                    BD("UPDATE $bd_table_accounts SET $bd_aServer=NULL WHERE $bd_aUserID='".$this->id."'");
         
            return true;
        }
     
        function gameLoginLast() {
        global $bd_table_accounts,$bd_aUserID,$bd_aServer;
     
            if (!$this->id) return false;
     
            $result = BD("SELECT gameplay_last FROM $bd_table_accounts WHERE gameplay_last<>'0000-00-00 00:00:00' and $bd_aUserID='".$this->id."'");
         
            if (mysql_num_rows( $result ) == 1) {
         
                $line = mysql_fetch_array($result);
             
                return $line['gameplay_last'];
             
            } else return false;     
         
            return true;
        }
     
        function login($tmp,$ip) {
        global $bd_table_accounts,$bd_aUserID,$bd_aTmp,$bd_aIP;
     
            if (!$this->id) return false;
     
            BD("UPDATE $bd_table_accounts SET $bd_aTmp='$tmp' WHERE $bd_aUserID='".$this->id."'");
            BD("UPDATE $bd_table_accounts SET $bd_aIP='".GetRealIp()."' WHERE $bd_aUserID='".$this->id."'");
     
            $this->tmp = $tmp;
         
            return true;
        }
     
        function logout() {
        global $bd_table_accounts,$bd_aTmp;
     
          if (!isset($_SESSION)) session_start();
          if (isset($_SESSION)) session_destroy();
       
          if (isset($_COOKIE['PRTCookie1']))
          {
           
              BD("UPDATE $bd_table_accounts SET $bd_aTmp='0' WHERE $bd_aTmp='".SQLComp($_COOKIE['PRTCookie1'])."'");
           
              setcookie("PRTCookie1","",time()-3600);
             
              $this->tmp = 0;
           
          }
     
        }
     
        function name()
        {
            return $this->name;
        }
     
        function getSkinFName() {
        global $way_mcraft,$way_skins;
            return $way_mcraft.$way_skins.$this->name.'.png';
        }
     
        function getCloakFName() {
        global $way_mcraft,$way_cloaks;
            return $way_mcraft.$way_cloaks.$this->name.'.png';
        }
     
        function deleteSkin() {
          if (file_exists($this->getSkinFName())) unlink($this->getSkinFName()); 
        }
     
        function deleteCloak() {
          if (file_exists($this->getCloakFName())) unlink($this->getCloakFName()); 
        }
     
        function deleteBuffer() {
        global $way_mcraft;
     
        $mini = $way_mcraft.'tmp/skin_buffer/'.$this->name.'_Mini.png';
        $skin = $way_mcraft.'tmp/skin_buffer/'.$this->name.'.png';
     
        if (file_exists($mini)) unlink($mini);
        if (file_exists($skin)) unlink($skin);
        }
     
        function changeName($newname) {
        global $bd_table_accounts,$bd_aUsername,$way_mcraft,$way_skins,$way_cloaks;
     
            if (!$this->id) return false;
     
            $newname = trim($newname);
         
            if (!preg_match("/^[a-zA-Z0-9_-]+$/", $newname)) return false;
         
            $result = BD("SELECT $bd_aUsername FROM $bd_table_accounts WHERE $bd_aUsername='".SQLComp($newname)."'");
     
            if (mysql_num_rows($result)) return false;
         
            if ((strlen($newname) < 4) or (strlen($newname) > 15)) return false;
         
            BD("UPDATE $bd_table_accounts SET $bd_aUsername='".SQLComp($newname)."' WHERE $bd_aUsername='".$this->name."'");
         
            if (!empty($_SESSION['user_name']) and $_SESSION['user_name'] == $this->name) $_SESSION['user_name'] = $newname;
             
            /* Переименование файла скина и плаща */
         
            $way_tmp_old = $way_mcraft.$way_skins.$this->name.'.png';
            $way_tmp_new = $way_mcraft.$way_skins.$newname.'.png';
         
            if (file_exists($way_tmp_old) and !file_exists($way_tmp_new)) rename($way_tmp_old, $way_tmp_new);
     
            $way_tmp_old = $way_mcraft.$way_cloaks.$this->name.'.png';
            $way_tmp_new = $way_mcraft.$way_cloaks.$newname.'.png';
         
            if (file_exists($way_tmp_old) and !file_exists($way_tmp_new)) rename($way_tmp_old, $way_tmp_new);
         
            $buff_mini    = $way_mcraft.'tmp/skin_buffer/'.$this->name.'_Mini.png';
            $buff_mini_new = $way_mcraft.'tmp/skin_buffer/'.$newname.'.png';
            $buff_skin    = $way_mcraft.'tmp/skin_buffer/'.$this->name.'.png';
            $buff_skin_new = $way_mcraft.'tmp/skin_buffer/'.$newname.'.png';
         
            if (file_exists($buff_mini)) rename($buff_mini, $buff_mini_new);
            if (file_exists($buff_skin)) rename($buff_skin, $buff_skin_new);
         
            $this->name = $newname;
         
            return true;
     
        }
     
        function changePassword($newpass,$pass = '',$check = false) {
        global $bd_table_accounts,$bd_aUsername,$bd_aPassword;
     
            require_once('instruments/password.php');
     
            if (!$this->id) return 0;
         
            if ($check) {
         
                $regular = "/^[a-zA-Z0-9_-]+$/";
             
                if (!preg_match($regular, $pass) or !preg_match($regular, $newpass)) return 11;
             
                $result = BD("SELECT $bd_aPassword FROM $bd_table_accounts WHERE $bd_aUsername='".$this->name."'");
                $line = mysql_fetch_array( $result );
             
                if ($line == NULL or !checkPass($line[$bd_aPassword],$pass)) return 12;
         
            }
             
            $minlen = 4; $maxlen = 15; $len = strlen($newpass);
         
            if (($len < $minlen) or ($len > $maxlen)) return 13;
             
            BD("UPDATE $bd_table_accounts SET $bd_aPassword='".createPass($newpass)."' WHERE $bd_aUsername='".$this->name."'");
         
            return 15;
        }
     
        function changeLvl($newlvl) {
        global $bd_table_accounts,$bd_aUsername,$bd_aPassword,$bd_aLvl;
     
            $newlvl = (int) $newlvl;
         
            if ($newlvl < 0 or $newlvl > 15) return false;
         
            BD("UPDATE $bd_table_accounts SET $bd_aLvl='".SQLComp($newlvl)."' WHERE $bd_aUsername='".$this->name."'");
         
            return true;
        }
     
        function id()
        {
            return $this->id;
        }
     
        function lvl()
        {
            return $this->lvl;
        } 
     
        function tmp()
        {
            return $this->tmp;
        }
     
        function ip()
        {
            return $this->ip;
        } 
     
        function email()
        {
            return $this->email;
        }
    }
     
    function SQLComp($text) {
    global $link;
       
    return mysql_real_escape_string($text, $link);
    }
     
    /* Системные функции */
     
    function tmp_name($folder,$pre = '',$ext = 'tmp'){
          $name  = $pre.time().'_';
       
          for ($i=0;$i<8;$i++) $name .= chr(rand(97,121));
       
          $name .= '.'.$ext;
       
          return (file_exists($folder.$name))? tmp_name($folder,$pre,$ext):$name;
    }
     
    function ratio($file,$baze = 64, $prop = 2) {
    $input_size = @getimagesize($file);
     
    if (empty($input_size)) return false;
     
    if (round($input_size[0] / $input_size[1], 2) != round($prop,2)) return false;
    else if ($input_size[0] < $baze) return false;
     
    $mp = $input_size[0] / $baze;
     
    return $mp;
    }
     
    function POSTGood($post_name, $format = 'png') {
     
    if ( empty($_FILES[$post_name]['tmp_name']) or
        $_FILES[$post_name]['error'] != UPLOAD_ERR_OK or
        !is_uploaded_file($_FILES[$post_name]['tmp_name']) or
        substr($_FILES[$post_name]['name'], 1 + strrpos($_FILES[$post_name]['name'], ".")) != $format
      ) return false;
     
    return true;
    }
     
    function POSTUpload($post_name, $final_way, $baze = 64, $prop = 2) {
    global $way_mcraft, $skin_size, $max_ratio;
     
    if (!is_dir($way_mcraft.'tmp/')) mkdir($way_mcraft.'tmp/', 0777);
     
    $tmp_file = $way_mcraft.'tmp/'.tmp_name($way_mcraft.'tmp/');
    if (!move_uploaded_file( $_FILES[$post_name]['tmp_name'], $tmp_file ))
    exit ('[Ошибка модуля загрузки] Убедитесь, что папка "'.$way_mcraft.'tmp/ " доступна для ЗАПИСИ.');
     
    $fsize = round($_FILES[$post_name]['size'] / 1024);
     
    if ( $skin_size < $fsize )
     
        { unlink($tmp_file); return 1; }
     
    $input_ratio = ratio($tmp_file, $baze, $prop);
         
    if (!$input_ratio or $input_ratio > $max_ratio) 
     
        { unlink($tmp_file); return 6; }
     
    if (file_exists($final_way)) unlink($final_way);
     
    if (rename( $tmp_file, $final_way )) chmod($final_way,0777);
    else exit ('[Ошибка модуля загрузки] Убедитесь, что папка "'.$way_mcraft.'tmp/ " доступна для ЧТЕНИЯ.');
     
    return 3;
     
    }
     
    function generateSessionId(){
        // generate rand num
        srand(time());
        $randNum = rand(1000000000, 2147483647).rand(1000000000, 2147483647).rand(0,9);
        return $randNum;
    }
     
    function randString( $pass_len = 50 ) {
        $allchars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $string = "";
     
        mt_srand( (double) microtime() * 1000000 );
     
        for ( $i=0; $i<$pass_len; $i++ )
        $string .= $allchars{ mt_rand( 0, strlen( $allchars )-1 ) };
     
        return $string;
    }
     
    function updateGameInfo($type,$value){
        global $bd_table_data;
     
        switch($type){
        case 'build': $query = BD("UPDATE $bd_table_data SET value='".SQLComp($value)."' WHERE property = 'latest-game-build'"); break;
        case 'launcher': $query = BD("UPDATE $bd_table_data SET value='".SQLComp($value)."' WHERE property = 'launcher-version'"); break;
        case 'state': $query = BD("UPDATE $bd_table_data SET value='".SQLComp($value)."' WHERE property = 'server-state'"); break;
        }
    }
     
    function getGameInfo($type){
        global $bd_table_data;
     
        switch($type){
        case 'build':
            $query = BD("SELECT * FROM $bd_table_data WHERE property = 'latest-game-build'"); 
                $resource = mysql_fetch_array($query);
                return $resource['value'];
        break;
     
        case 'launcher':
            $query = BD("SELECT * FROM $bd_table_data WHERE property = 'launcher-version'");
                $resource = mysql_fetch_array($query);
                return $resource['value'];
        break;
     
        case 'state':
            $query = BD("SELECT * FROM $bd_table_data WHERE property = 'server-state'");
                $resource = mysql_fetch_array($query);
                return $resource['value'];
        break;
        }
    }
     
    function GetRealIp(){
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) $ip=$_SERVER['HTTP_CLIENT_IP'];
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    else $ip=$_SERVER['REMOTE_ADDR'];
    return $ip;
    }
     
    function CanRegister() {
    global $link,$bd_table_ipban;
     
        $ip = $_SERVER['REMOTE_ADDR']; //если нужен реальный адрес пользователя используйте GetRealIp
        $result = BD("SELECT ban_until FROM $bd_table_ipban WHERE IP='$ip'");
        $line = mysql_fetch_array($result);
     
        if ( ($line != NULL) and ($line['ban_until']!='0000-00-00 00:00:00') )
        {
            mysql_close( $link );
            return false;
        }
     
        return true;
                     
    }
     
    function RefreshBans() {
    global $next_registration_time,$bd_table_ipban;
     
        BD("DELETE FROM $bd_table_ipban WHERE (ban_until='0000-00-00 00:00:00') AND (time_start<NOW()-INTERVAL $next_registration_time HOUR)");
        BD("DELETE FROM $bd_table_ipban WHERE (ban_until<>'0000-00-00 00:00:00') AND (ban_until<NOW())");
                     
    }
     
    function vtxtlog($string) {
    global $system_log;
     
    if (!$system_log) return;
     
    $log_file = "log.txt";
     
        if (file_exists($log_file) and round(filesize ($log_file) / 1048576) >= 50) unlink($log_file);
     
        $fp=fopen($log_file,"a");
     
        fwrite($fp,$string."\r\n");
        fclose($fp);
     
     
    }
     
    define("FEEDBACK", '<a href="http://drop.catface.ru/index.php?nid=17">WebMCR 1.8</a> &copy; 2012 NC22');
     
    /* Проверяем сессию на сайте */
     
    $user = false;
     
    if (!session_id() and isset($_GET['sid'])) session_id($_GET['sid']);
             
    if (!isset($_SESSION)) session_start();
     
    if (isset($_SESSION['user_name']) AND $_SESSION['ip'] == $_SERVER['REMOTE_ADDR']) {
        $user = new User($_SESSION['user_name'],$bd_aUsername);
    if (!$user->id()) $user = false;
    }
     
    if (isset($_COOKIE['PRTCookie1']) and empty($user)) {
     
      $user = new User($_COOKIE['PRTCookie1'],'tmp');
     
        if (!$user->id()) {
            $user = false;
            setcookie("PRTCookie1","",time(), '/');
        } else {
            if (!isset($_SESSION)) session_start();
            $_SESSION['user_name'] = $user->name();
            $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
        }
     
    }
     
    if (!empty($user)) {
     
        if (!strncmp($user->tmp(),'ipcheck_',8) and GetRealIp() != $user->ip()) $user = false;
        elseif ($user->lvl() <= 0) {$user->logout(); $user = false;}
     
    }
     
    ?>
    +таблицы

    [​IMG]
     
  6. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    Поставил твою веб часть под этот клиент. Пошло дело, НО... :)
    если запускаю сервер с onlinemide=false, то могу зайти через оф лаунчер без проблем(с сервером ошибок нет)
    если ставлю true, то через лаунчер от maximusorg выдает ошибку "Конец потока"
     
  7. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Не должно такого быть проблема с хостом или ссылки криво указал в клиенте и сервере.
     
  8. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    Сервер на собственной машине, да и к тому же через оф лаунчер подключается. А ссылке только 2, так?
    в клиенте ayh.class и mcpc+ сервер - iu.class. Прописал ссылки до joinserver и checkserver. Проверил, что php файлы доступны, если подключаться через браузер(пишет bad login и тд). Мб нужно выдать папке и php файлам какие то права? Типа 666, 777 или как они там (не особо разбираюсь)
     
    caNek нравится это.
  9. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    Видна ошибка если запустить через netbeans:
    Код:
    2013-03-02 15:38:25 [INFO] [STDERR] minecraft.jar (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] C:\Users\Ilya\AppData\Roaming\.minecraft\bin\client.zip (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] C:\Users\Ilya\AppData\Roaming\.minecraft\bin\windows_natives.jar (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] minecraft.jar (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] C:\Users\Ilya\AppData\Roaming\.minecraft\bin\client.zip (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] C:\Users\Ilya\AppData\Roaming\.minecraft\bin\windows_natives.jar (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] minecraft.jar (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] C:\Users\Ilya\AppData\Roaming\.minecraft\bin\client.zip (Не удается найти указанный файл)
    2013-03-02 15:38:26 [INFO] [STDERR] C:\Users\Ilya\AppData\Roaming\.minecraft\bin\windows_natives.jar (Не удается найти указанный файл)
    Под спойлером скорее всего не верное предположения и к ошибке дело не имеет, но всё же:
    Кажется нашел в чем причина. Установил папку с игрой что для оф лаунчера, что для лаунчера от maximusorg одну и туже папку. Запускаю лаунчера от maximusorg как положено закачивает клиент(если его нет, если есть пропускает) при этом ошибка "конец потока", выключаю, затем запускаю оф. лаунчер и это паразит что то качает, при этом захожу спокойно на сервер, когда запускаю опять лаунчера от maximusorg, то он перекачивает клиент. Оф лаунчер меняет папку NATIVE. Возможно мне стоит скачать какой нибудь новый windows_native.jar.lzma? (я так понимаю из windows_native распаковывается папка NATIVE)
     
    Stalkerdeni971 нравится это.
  10. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    скачал клиент имерии все заработало.
     
  11. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    От куда вы такие криворукие беретесь :trf:?
     
  12. Автор темы
    iZuk

    iZuk Активный участник Пользователь

    Баллы:
    68
    дать бы тебе план работ с чертежами и чтоб за одно сметы составил, вот и посмотрим кто криворукий или у кого мозги на бекрень.
    Дело не в криворукости, а в неопытности.
    Не надо хамить, это не красиво :)
     

Поделиться этой страницей