В прошлой статье, помимо всего прочего, я рассказывал, как можно запустить Quake для DOS, загрузив DOS на современном компьютере. Отказ от использования эмуляторов позволяет погрузиться в прошлое наиболее реалистично, однако есть ряд недостатков:
- не на всех компьютерах можно поиграть со звуком;
- необходимо заменять файл в дистрибутиве Quake;
- невозможно поиграть по сети.
В этой статье я приведу решение, лишённое этих недостатков. Хотя оно подразумевает использование эмуляции, возможность игры в интернете позволяет забыть об этом. Обладая минимальными знаниями по работе в Linux, любой желающий может повторить это решение у себя.
Исходный код решения вы можете найти в моём репозитории на GitHub. Использовать его можно по своему усмотрению. Загрузить и запустить или воспользоваться для прояснения моментов, которые могут оказаться сложными, — решать вам.
Когда я учился на первом и втором курсах института, игра Quake была хитом. Играли в неё в компьютерных клубах или дома, если кто-то был редким обладателем компьютера. Мы, студенты, всегда искали возможность поиграть в неё в компьютерном классе — уж очень привлекательны были сетевые возможности Quake для нас, людей, не избалованных современным интернетом. Даже те, у кого был компьютер дома, приходили в институт из-за возможности поиграть по локальной сети.
Локальная сеть была организована на основе протоколов IPX/SPX. Про TCP/IP можно было почитать в журналах или умных книжках, которые мы, к сожалению, тоже редко видели.
Сегодня вы можете вернуть себе и вашим друзьям те ощущения азарта от сетевой игры в Quake для DOS. Причём неважно, где находятся ваши друзья — главное, чтобы у них было стабильное и относительно быстрое интернет-соединение.
Для меня сам факт того, что ты играешь в ту самую игру, в которую играл более 25 лет назад, вызывает приятные приступы ностальгии. Надеюсь, я не одинок.
В 90-е в компьютерных классах моего института стояли компьютеры без звуковых карт, поэтому игра мне запомнилась без звука. Сейчас же, используя эмуляцию, можно будет поиграть со звуком.
Что понадобится
- Эмулятор DOSBox Staging.
- VPS с Linux. Например, с Ubuntu 20.04.
- Docker и утилита docker-compose.
- Файлы игры Quake для DOS, которые можно найти в интернете.
Немного теории
Для начала нам не повредит немного теории. Если читатель знаком с теорией или она ему не нужна, то можно сразу перейти к делу.
▍ Технологии виртуализации и эмуляции
Виртуализация и эмуляция сейчас используются практически везде. На это есть ряд причин:
- экономятся ресурсы, так как на одном физическом компьютере могут работать несколько виртуальных компьютеров;
- независимость от платформы, так как можно работать с программами для архитектур, физических реализаций которых у вас нет;
- упрощается развёртывание приложений, так как вы без труда можете создать виртуальную машину, содержащую нужное вам программное и аппаратное обеспечение.
VPS, Docker и эмулятор DosBox Staging, используемые в статье, относятся к этим технологиям.
▍ Компьютерные сети
Сети бывают локальные и глобальные. Проблема глобальных сетей в том, что каждый узел глобальной сети обязан иметь глобальный IP-адрес, а этих адресов не так уж и много по современным меркам. Поэтому часто провайдеры не выдают своим клиентам глобальные IP-адреса, а используют технологию NAT.
▍ NAT
С большой долей вероятности доступ в интернет вам предоставляется с помощью Network Address Translation (NAT), поэтому кратко рассмотрим эту технологию, не вдаваясь в скучные и утомительные подробности.
NAT позволяет нескольким компьютерам использовать один и тот же глобальный IP-адрес в интернете. Среднестатистический пользователь в большинстве случаев не заметит разницы, разделяет ли он IP-адрес в интернете с кем-то или нет. Исключением может быть ситуация, когда он увидит на каком-нибудь сайте сообщение, что его IP-адрес забанен из-за большого количества запросов, или когда у него возникнут сложности с загрузкой редкого торрента.
Но если вы захотите создать на своём компьютере сервер, а ваш провайдер предоставляет доступ с использованием NAT, то обратиться к серверу из интернета будет сложно или вообще невозможно. Поэтому часто для размещения своих серверов в интернете используют технологию Virtual Private Server (VPS).
▍ Virtual Private Server
Организации, которые предоставляют услугу VPS, называются хостинг-провайдерами. До того, как технологии виртуализации вошли в нашу жизнь, хостинг-провайдеры предоставляли менее удобные (Website Hosting) и более дорогие (Dedicated Server) услуги. Хотя и сейчас вы можете себе их заказать.
У хостинг-провайдера есть определённый пул физических компьютеров, а пользователями арендуются виртуальные машины (компьютеры), запускаемые на компьютерах из этого пула.
Эта услуга выгодна как провайдеру, так и конечному пользователю. Провайдер может более рационально использовать имеющийся у него пул физических компьютеров, а пользователь получает виртуальный компьютер, почти не отличающийся от реального, по гораздо меньшей цене, чем в случае аренды реального компьютера.
Благодаря современным графическим пользовательским интерфейсам провайдера, создание VPS осуществляется быстро и удобно, всего за несколько минут.
Пользователи получают полноценный узел в интернете, который могут использовать по своему усмотрению. Это может быть персональный сайт, VPN-сервер, игровой сервер. Применение ограничивается только фантазией, знаниями и умениями пользователя.
Многие задачи по администрированию VPS выполняются на стороне хостинг-провайдера. Пользователям не нужно заботиться о том, чтобы компьютер работал 24/7 — это задача провайдера. Инфраструктура провайдера адаптирована к различным непредвиденным случаям вроде отключения электричества или поломки жёсткого диска.
▍ Туннелирование в компьютерных сетях
Суть туннелирования заключается в том, что пакеты из одного протокола передачи данных помещаются без изменения в пакеты другого для передачи по сети. Говорят, что второй протокол является транспортным протоколом для другого. Чаще всего туннелирование, обычно совместно с шифрованием, используется для организации VPN (Virtual Private Network).
В нашем случае мы будем использовать UDP-туннель для передачи пакетов IPX. Иными словами, пакеты IPX будут упаковываться в пакеты UDP и передаваться в сети. Это сделает возможным использование протокола IPX в интернете.
▍ Firewall
Если вы размещаете сервер в интернете, то вам лучше защитить его при помощи Firewall. В Firewall прописываются правила, которые определяют на базовом уровне, откуда можно обратиться к вашему серверу и к каким службам сервера. К счастью, большинство провайдеров VPS позволяют очень просто настроить эти правила из графического интерфейса.
Используемые приложения
▍ DOSBox Staging
Ранее я практически не сталкивался с этим эмулятором. Если я хотел запустить приложения для DOS, то использовал виртуальные машины (VMWare Player, VMWare Workstation, Oracle Virtual Box) или эмуляторы (Bochs, Qemu). Попробовав DOSBox, а потом и DOSBox Staging, я понял для себя, что последний лучше всего подходит для запуска старых игр для DOS.
Изначально я недооценивал этот эмулятор, считая его просто упрощённой версией VMWare, Virtual Box или Qemu. Однако из-за того, что его назначение узкоспециализированное – эмуляция DOS, его скорость и точность эмуляции впечатляют.
По моим ощущениям совместимость с программами для DOS у него гораздо выше, чем у упомянутых ранее виртуальных машин и эмуляторов. Он великолепно эмулирует работу звуковых карт, сетевой протокол IPX, что для меня ранее казалось проблематичным. Если DOS-программа не воспроизводила звук или нельзя было воспользоваться её сетевыми возможностями, я делал поправку на то, что всё-таки прошло много времени, и, раз не работает, можно опустить этот момент.
▍ Ipxbox
IPX-сеть можно создать, используя команду ipxnet startserver в консоли DOSBox Staging, но это решение не очень удобное, если размещать сервер IPX на VPS. Поэтому, я думаю, лучше использовать внешний по отношению к DOSBox IPX-сервер. Варианты внешних серверов с сайта DOSBox, оказались слишком устаревшими, и мне не удалось быстро заставить их работать, поэтому я воспользовался ipxbox.
Ipxbox — это программа, написанная на языке Go, позволяющая организовывать IPX-сеть из экземпляров DOSBox в TCP/IP сети. Если интересно, что ещё позволяет делать программа, можете посмотреть дополнительную информацию на сайте или на YouTube-канале автора программы.
▍ Docker
Чем больше я использую Docker, тем больше убеждаюсь в том, что это универсальное решение, которому можно найти всё больше и больше применений. В нашем случае я создал Docker-образы dedicated-сервера Quake и программы ipxbox.
Вероятно, можно было найти уже современную реализацию сервера Quake для Linux и упаковать его в Docker-образ, но тогда нужно было бы думать, как настроить TCP/IP в DOS. Поэтому я решил создать докер-образ с Quake для DOS, а не Linux. Получилось интересное, на мой взгляд, и работающее решение – Quake для DOS, запускаемый в Docker-контейнере.
▍ Утилита docker-compose
Нам понадобится несколько Docker-контейнеров: один контейнер с IPX-сервером и один или несколько контейнеров с Quake-серверами. Управлять таким вроде бы и небольшим разнообразием уже не так удобно, как одним контейнером, поэтому нам поможет утилита docker-compose.
Docker-compose позволяет создавать несколько Docker-контейнеров и управлять ими. Структура мультиконтейнерного приложения описывается в файле docker-compose.yml.
Реализация
▍ Настройка Quake на локальном компьютере
- Загружаем Quake с сайта archive.org.
- Распаковываем содержимое архива в папку, например, C:\Games\quake.
- Меняем содержимое файла start.bat на
QUAKE.EXE -nocdaudio
. - Загружаем DOSBox Staging.
- Устанавливаем, запускаем и закрываем DOSBox Staging. Устанавливать лучше только для своего пользователя.
- Модифицируем файл %USERPROFILE%\AppData\Local\DOSBox\dosbox-staging.conf, чтобы удобнее было запускать в дальнейшем.
...
[ipx]
ipx = true
[autoexec]
mount c: c:\games
c:
cd quake
Теперь в DOSBox Staging для запуска Quake можно будет просто ввести в консоли start.
▍ Организация сетевого варианта игры Quake
Если у вас есть локальная сеть, то перед запуском Quake можно на одном из компьютеров запустить IPX-сервер при помощи команды в DOSBox консоли:
DOSBOX> ipxnet startserver 10000
Где 10000 — это номер UDP-порта, на котором будет запущен IPX-сервер. Разумеется, вы можете использовать другой порт.
Остальные игроки в локальной сети могут подключиться к этой созданной IPX-сети с помощью команды:
DOSBOX> ipxnet connect your.machine 10000
Где your.machine — это IP-адрес или доменное имя компьютера, на котором запущен IPX-сервер.
Теперь вы можете играть по сети, только сеть локальная, а подключиться к ней из интернета будет проблематично. Я решил эту проблему путём создания общедоступного сервера IPX в сети Internet. Чтобы всех игроков поставить в равные условия, я также создал dedicated-сервер Quake, а вернее два, чтобы добавить универсальности решению.
▍ Настройка общедоступного сервера IPX и dedicated-сервера Quake
Самый простой способ запустить IPX-сервер и dedicated Quake сервера — загрузить созданный мной docker-compose.yml файл из интернета и выполнить в директории с файлом docker-compose.yml следующую команду:
$ docker-compose up -d
Чтобы остановить и удалить сервера, выполняются команды:
$ docker-compose stop
$ docker-compose rm
Если вы хотите узнать, как сделать такой файл самим и больше подробностей, то ниже приведена инструкция.
Структуру проекта и содержимое файлов вы можете посмотреть в репозитории, ниже привожу описание только самых важных из них.
Для ясности структура директорий с файлами приведена на рисунке.
Структура проекта
▍ 1. Создаём Docker-образ для IPX-сервера
FROM ubuntu:22.04 as builder
RUN apt-get update && apt install --yes golang libpcap-dev openssl ca-certificates
RUN mkdir -p /app/
WORKDIR /app/
RUN go mod init m.test
ARG CERT_LOCATION=/usr/local/share/ca-certificates
RUN mkdir -p ${CERT_LOCATION}
RUN openssl s_client -showcerts -connect github.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${CERT_LOCATION}/github.crt
RUN openssl s_client -showcerts -connect proxy.golang.org:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${CERT_LOCATION}/proxy.golang.crt
RUN update-ca-certificates
RUN go get github.com/fragglet/ipxbox
RUN go build github.com/fragglet/ipxbox
FROM ubuntu:22.04
RUN apt-get update
RUN apt install --yes libpcap-dev
WORKDIR /app
COPY --from=builder /app/ipxbox /app/ipxbox
CMD ./ipxbox --port 10000
Файл ipxbox/DockerfileЧтобы созданный Docker-образ содержал меньше ненужных данных, в Dockerfile описываем так называемый multistage build. Он подразумевает, что в одном Dockerfile описывается один Docker-образ со средой для сборки, а второй для размещения собранных файлов. В результате Docker-образ будет занимать меньше места на диске.
▍ 2. Создаём Docker-образ для Quake-сервера
FROM ubuntu:20.04
RUN apt update && apt install --yes software-properties-common
RUN add-apt-repository ppa:feignint/dosbox-staging && \
apt update && \
apt install --yes dosbox-staging gettext
RUN mkdir -p /app/quake
COPY quake/ /app/quake
ENV SDL_VIDEODRIVER=dummy
ENV IPX_SERVER_ADDRESS=192.168.0.161
ENV IPX_SERVER_PORT=10000
ENV QUAKE_SERVER_NAME="DEFAULT SERVER"
COPY dosbox-staging.conf.templ /app/dosbox-staging.conf.templ
COPY quake-config.cfg.templ /app/quake-config.cfg.templ
COPY start.sh /app/start.sh
RUN chmod 777 /app/start.sh
CMD /app/start.sh
Файл quake-server/DockerfileПри запуске Docker-контейнера у нас будут добавлены следующие переменные окружения: SDL_VIDEO_DRIVER, IPX_SERVER_ADDRESS, IPX_SERVER_PORТ и QUAKE_SERVER_NAME.
SDL_VIDEO_DRIVER нужно проинициализировать значением dummy, чтобы DOSBox запустился в так называемом headless mode, т. е. без использования графических возможностей. Для сервера они нам не нужны.
IPX_SERVER_ADDRESS и IPX_SERVER_PORT нужны, чтобы указать DOSBox, где находится IPX-сервер.
QUAKE_SERVER_NAME — это имя dedicated Quake-сервера, который будет отображаться в списке при подсоединении к сетевой игре.
Файлы dosbox-staging.conf.templ и quake-config.cfg.templ — это шаблоны конфигураций DOSBox и Quake, которые преобразовываются в файлы конфигурации при запуске скрипта start.sh.
Скрипт start.sh, помимо этого, ещё выполняет задержку в 10 секунд перед запуском dedicated Quake-сервера. Это нужно, чтобы IPX-сервер успел загрузиться до запуска dedicated Quake-сервера. Решение неэлегантное, но на первый случай сгодится ввиду своей простоты.
Для скрипта start.sh устанавливаются атрибуты 777, чтобы его можно было запустить. По умолчанию git не хранит атрибуты файлов — можно или повозиться с настройкой Git или воспользоваться этим решением.
▍ 3. Описываем структуру мультиконтейнерного Docker-приложения
version: "3.9"
services:
ipxserver:
restart: always
build: ipxbox/.
ports:
- "10000:10000/udp"
image: "artyomsoft/ipxbox"
gameserver1:
restart: always
build: quake-server/.
depends_on:
- ipxserver
environment:
- IPX_SERVER_ADDRESS=ipxserver
- IPX_SERVER_PORT=10000
- QUAKE_SERVER_NAME=DEFAULT_S1
image: "artyomsoft/quake-server"
gameserver2:
restart: always
build: quake-server/.
depends_on:
- ipxserver
environment:
- IPX_SERVER_ADDRESS=ipxserver
- IPX_SERVER_PORT=10000
- QUAKE_SERVER_NAME=DEFAULT_S2
image: "artyomsoft/quake-server"
Файл docker-compose.ymlФайл docker-compose.yml, думаю, понятен без дополнительных пояснений.
▍ 4. Выполняем запуск мультиконтейнерного приложения
$ docker-compose up --build --force-recreate -d
Опция build нужна, чтобы перед запуском контейнеров собрались образы для них, опция --force-recreate нужна, чтобы контейнеры пересоздавались при запуске, а опция d, чтобы они запускались в фоне.
▍ 5. Запускаем DOSBox c Quake и проверяем работу с нашим мультиконтейнерным приложением
DOSBOX> ipxnet connect 127.0.0.1 10000
DOSBOX> start
▍ 6. Выходим из DOSBox, останавливаем и удаляем Docker-контейнеры
$ docker-compose stop
$ docker-compose rm
▍ 7. Делаем релиз мультиконтейнерного приложения
Собираем и пушим образы на DockerHub:
$docker-compose build
$doker-compose push
Для хранения исходного приложения я использовал GitHub. Вы также можете создать публичный репозиторий на GitHub и поместить приложение туда.
Shell в Linux трепетно относится к окончаниям строк в файлах *.sh, поэтому убедитесь, что у вас файлы *.sh имеют Unix-окончание строк и явно пропишите это в файле .gitattributes.
Создайте репозиторий на GitHub, а потом у себя в корне проекта выполните следующие команды:
$ git init
$ git add .
$ git remote add origin <ссылка на ваш репозиторий>
$ git commit -m "Initial commit"
$ git push -u master origin
После успешного пуша репозитория на github создайте release и добавьте туда файл docker-compose.yml. Это позволит удобно скачивать этот файл по HTTP.
▍ 8. Выбираем VPS
Выбор VPS ограничивается вашими предпочтениями, финансовыми возможностями и требованиями созданного мультиконтейнерного Docker-приложения к ресурсам. В современных реалиях проблематично для жителей РФ арендовать VPS у иностранного хостинг-провайдера, поэтому нужно искать отечественный. Так как я хотел сделать всё быстро и просто, запустил своё приложение на тарифном плане Start от RUVDS. Проблем с производительностью я не заметил.
За стоимость двух поездок в метро или бургера вы получаете на месяц в пользование VPS, позволяющий вам играть в Quake для DOS по интернету с друзьями. Если вы сомневаетесь, можно заказать пробный период на 3-е суток (для новых пользователей) или воспользоваться другим хостинг-провайдером на ваш выбор.
Чтобы получить VPS, от вас требуется минимальная последовательность шагов:
- Регистрация аккаунта.
- Выбор тарифа для VPS и конфигурации сервера.
- Оплата.
Из всех параметров конфигурации сервера для тарифа Start, предложенных RUVDS, я поменял только операционную систему на Ubuntu 20.04 и через несколько минут я получил готовый VPS, к которому можно было присоединиться при помощи PuTTY или другого SSH-клиента.
Конфигурация моего VPS
Если вы выберете расположение VPS за пределами РФ, стоимость его будет выше, но нам для Quake достаточно и на территории РФ.
RUVDS не является регистратором доменов, и если вы хотите, чтобы у вашего VPS было доменное имя, а не только IP-адрес, нужно у регистратора домена получить доменное имя и прописать адреса DNS RUVDS, а в личном кабинете на сайте RUVDS добавить полученное доменное имя к созданному VPS.
Адреса DNS RUVDS
Привязка доменного имени к VPS
▍ 9. Настраиваем Firewall
Для более безопасной работы VPS-сервера желательно настроить Firewall. Firewall настраиваем не в VPS, а на сайте хостинг-провайдера — это гораздо удобнее и требует от вас минимальных знаний.
- В вашем личном кабинете на сайте RUVDS выбираем созданный VPS.
- Заходим в настройки Firewall. Сеть -> Настроить фаервол для публичных адресов.
- Запрещаем все входящие соединения за исключением SSH и порта 10000 (на котором работает наш ipxbox). Для большей безопасности можно ещё разрешить доступ по SSH только с определённых IP адреса/адресов.
- Упорядочиваем правила как на рисунке ниже.
Правила Firewall - Нажимаем кнопку «Применить текущий набор правил».
▍ 10. Устанавливаем Docker и docker-compose на VPS
- Подключаемся к VPS по SSH.
- Вводим пользователя и пароль для VPS сервера.
- Вводим команды, приведённые ниже.
$apt update
$ apt install --yes docker.io curl
$ curl -SL https://github.com/docker/compose/releases/download/v2.15.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
$ ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
$ systemctl enable docker
Так как теперь Docker прописан в автозагрузку (команда systemclt enable docker), то и мультиконтейнерные приложения будет перезапускаться при перезагрузке VPS.
▍ 11. Загружаем и запускаем мультиконтейнерное приложение на VPS
$ cd ~
$ mkdir quake-servers
$ cd quake-servers
$ curl -SL <http адрес вашего docker-compose.yml> -o docker-compose.yml
$ docker-compose up -d
Если вы создали свой GitHub-репозиторий и релиз в нём, то используйте http-ссылку на docker-compose.yml из него. Важно, чтобы VPS мог каким-то образом получить docker-compose.yml. А docker-compose мог загрузить и запустить Docker-образ.
▍ 12. Запускаем DOSBox Staging на локальном компьютере
DOS BOX> ipxnet connect <адрес вашего VPS> 10000
DOS BOX> start
▍ 13. Выбираем в Quake сетевую игру и протокол IPX, подключаемся к серверу Quake
Выбор севера Quake
Игровой процесс
Вы можете запустить два экземпляра DOSBox c Quake и таким образом проверить, как они работают по сети вместе.
Теперь вы можете делиться с друзьями адресом вашего ipxbox и играть с ними по сети в Quake для DOS, вспоминая те добрые времена. А ещё можно создать групповой звонок в Telegram, и тогда вы сможете делиться своими эмоциями голосом во время игры.
Заключение
Чтобы заставить всё работать как надо, я перепробовал несколько вариантов решения проблемы. Например, для создания IPX-сервера я изначально использовал эмулятор DOSBox, но потом посчитал, что использование выделенного сервера для IPX более элегантное решение.
Вместо Docker и docker-compose можно было обойтись systemd, но такое решение мне кажется более сложным и менее переносимым.
Моё решение годится небольшой компании для развлекательных целей, так как создание решения уровня production требует значительных доработок.
В частности, я знаю про следующие недостатки:
- При перезагрузке сервера IPX нужно отсоединиться и подсоединиться к IPX-сети в DOXBox Staging.
- Логирование из DosBox Staging некорректно работает в Docker-контейнере.
- Зная IP-адрес, пароль и порт сервера к нему может присоединиться любой пользователь.
- У серверов нет доменного имени, только IP-адрес.
- Не рассматривались вопросы масштабирования и отказоустойчивости.
- Docker-образы не оптимизировались по размеру.
- Quake-серверы просто ожидают несколько секунд запуска IPX-сервера, не проверяя, реально он загружен или нет. Поэтому теоретически при запуске Docker-контейнеров Quake-сервер может не найти IPX-сервер.
- Я не являюсь экспертом в настройке Quake. Я только настроил всё так, чтобы работало.
Несмотря на развлекательный характер статьи, вы получили базовые знания и умения по работе c VPS, узнали о технологиях виртуализации, базово научились пользоваться Firewall. Если у вас всё получилось, могу пожелать вам удачи в дальнейшем изучении Linux и сетевых технологий. Если нет, то попробуйте прочитать статью ещё раз, задать вопросы в комментариях или на форумах и сайтах на ваш выбор. Главное — правильно сформулировать вопрос, и у вас всё получится.
Говорят, что, если у вас что-то не получается с первого раза — это даже хорошо, так как вы больше изучите и запомните. Скажу по секрету, у меня тоже не всё было гладко с первого раза, так что дерзайте.
Играй в наш скролл-шутер прямо в Telegram и получай призы!
Поделиться ссылкой:
Интересные статьи
Интересные статьи
Привет! На связи Данила Соловьев, руководитель направления PHP в AGIMA. Для проджект-менеджеров и джуниор-разработчиков я подготовил небольшой гайд по тому, как ускорять работу крупных проектов на Бит...
PlayStation 5 и Xbox Series X были выпущены уже больше года назад, но глобальная нехватка компьютерных чипов по-прежнему затрудняет их поставки и завышает цены. Дефицит дополнительно усугубляется ...
Для начала пару слов об обработке текстовой информации, рекуррентных сетях и методах защиты конфиденциальности пользователя.Рекуррентные нейронные сети (Recurrent Neural Networks, RNNs) — популяр...
Многие бизнес-аналитики уверены, что даже после возврата общества и бизнеса к относительно нормальной жизни после пандемии COVID-19, рост рынка унифицированных коммуникаций уже не остано...
Ваш сайт работает на 1С-Битрикс? Каждому клиенту вы даёте собственную скидку или назначаете персональную цену на товар? Со временем в вашей 1С сложилась непростая логика ценообразования и формирования...