Множественные изменения и улучшения:

* Удалил все типы вложений, теперь типы вложений реализуются в библиотеках для каждого конкретного мессенджера.
* Теперь сохраняется история перемещения пользователя по сценарию. Сохраняется сообщение и название юнита. Это позволяет откатывать пользователя назад.
* Реализовал два новых юнита. RollBackCmd позволяет откатить пользователя назад в сценарии на произвольное количество юнитов. TeleportCmd позволяет перенести пользователя в произвольное место сценария.
* Удалил AnswerProcessing, вместо него можно использовать AnswerText.
This commit is contained in:
Struchkov Mark 2022-07-10 00:25:53 +03:00
parent 78b2dda570
commit 996194264e
54 changed files with 890 additions and 564 deletions

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>dev.struchkov.godfather</groupId> <groupId>dev.struchkov.godfather</groupId>
<artifactId>godfather-bot</artifactId> <artifactId>godfather-bot</artifactId>
<version>0.0.8</version> <version>0.0.9</version>
</parent> </parent>
<artifactId>bot-context</artifactId> <artifactId>bot-context</artifactId>
@ -15,6 +15,10 @@
<description>Доменные сущности, интерфейсы, для библиотеки Godfather</description> <description>Доменные сущности, интерфейсы, для библиотеки Godfather</description>
<dependencies> <dependencies>
<dependency>
<groupId>dev.struchkov</groupId>
<artifactId>autoresponder</artifactId>
</dependency>
<dependency> <dependency>
<groupId>dev.struchkov.haiti</groupId> <groupId>dev.struchkov.haiti</groupId>
<artifactId>haiti-utils</artifactId> <artifactId>haiti-utils</artifactId>

View File

@ -1,6 +1,4 @@
package dev.struchkov.godfather.core.domain; package dev.struchkov.godfather.context.domain;
import dev.struchkov.godfather.context.domain.BoxAnswer;
public class Clarification { public class Clarification {

View File

@ -0,0 +1,35 @@
package dev.struchkov.godfather.context.domain;
import dev.struchkov.godfather.context.domain.content.Message;
public class StorylineHistory extends BasicEntity {
private Long personId;
private String unitName;
private Message message;
public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
public String getUnitName() {
return unitName;
}
public void setUnitName(String unitName) {
this.unitName = unitName;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
}

View File

@ -1,4 +1,6 @@
package dev.struchkov.godfather.core.utils; package dev.struchkov.godfather.context.domain;
import static dev.struchkov.haiti.utils.Exceptions.utilityClass;
/** /**
* Тип Unit-а. Обределяет способ обработки. * Тип Unit-а. Обределяет способ обработки.
@ -9,14 +11,15 @@ public class TypeUnit {
public static final String TEXT = "TEXT"; public static final String TEXT = "TEXT";
public static final String SAVE = "SAVE"; public static final String SAVE = "SAVE";
public static final String PROCESSING = "PROCESSING";
public static final String TIMER = "TIMER"; public static final String TIMER = "TIMER";
public static final String CHECK = "CHECK"; public static final String CHECK = "CHECK";
public static final String VALIDITY = "VALIDITY"; public static final String VALIDITY = "VALIDITY";
public static final String ACCOUNT = "ACCOUNT"; public static final String BACK_CMD = "BACK_CMD";
public static final String TELEPORT_CMD = "TELEPORT_CMD";
private TypeUnit() { private TypeUnit() {
throw new IllegalStateException("Утилитарный класс"); utilityClass();
} }

View File

@ -0,0 +1,34 @@
package dev.struchkov.godfather.context.domain;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
/**
* Сущность инкапсулирует в себе данные, необходимые для обработки сценария.
*
* @param <U> Тип юнита
* @param <M> Тип сообщения
*/
public class UnitRequest<U extends MainUnit, M extends Message> {
private final U unit;
private final M message;
private UnitRequest(U unit, M message) {
this.unit = unit;
this.message = message;
}
public static <U extends MainUnit, M extends Message> UnitRequest<U, M> of(U mainUnit, M message) {
return new UnitRequest<>(mainUnit, message);
}
public U getUnit() {
return unit;
}
public M getMessage() {
return message;
}
}

View File

@ -7,6 +7,8 @@ import javax.persistence.Entity;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
@ -33,9 +35,9 @@ public class Mail extends Message {
/** /**
* Вложения к сообщению. * Вложения к сообщению.
*/ */
@OneToMany(fetch = FetchType.EAGER)
@Column(name = "attachment") @Column(name = "attachment")
private List<Attachment> attachments; @OneToMany(fetch = FetchType.LAZY)
private List<Attachment> attachments = new ArrayList<>();
/** /**
* Пересланные сообщения. * Пересланные сообщения.
@ -68,8 +70,12 @@ public class Mail extends Message {
return attachments; return attachments;
} }
public void setAttachments(List<Attachment> attachments) { public void addAttachment(Attachment attachment) {
this.attachments = attachments; this.attachments.add(attachment);
}
public void addAttachments(Collection<Attachment> attachments) {
this.attachments.addAll(attachments);
} }
public List<Mail> getForwardMail() { public List<Mail> getForwardMail() {

View File

@ -2,10 +2,7 @@ package dev.struchkov.godfather.context.domain.content.attachment;
import dev.struchkov.godfather.context.domain.BasicEntity; import dev.struchkov.godfather.context.domain.BasicEntity;
import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
/** /**
* Абстрактная сущность, для всех вложений к сообщениям от пользователей. * Абстрактная сущность, для всех вложений к сообщениям от пользователей.
@ -15,15 +12,6 @@ import javax.persistence.Enumerated;
@Entity @Entity
public abstract class Attachment extends BasicEntity { public abstract class Attachment extends BasicEntity {
/** public abstract String getType();
* Тип сущности.
*/
@Column(name = "type")
@Enumerated(value = EnumType.STRING)
protected AttachmentType type;
public AttachmentType getType() {
return type;
}
} }

View File

@ -1,14 +0,0 @@
package dev.struchkov.godfather.context.domain.content.attachment;
/**
* Тип вложения {@link Attachment} к сообщению.
*
* @author upagge [08/07/2019]
*/
public enum AttachmentType {
AUDIO_MESSAGE,
GEO,
LINK
}

View File

@ -1,25 +0,0 @@
package dev.struchkov.godfather.context.domain.content.attachment;
import java.net.URL;
/**
* Вложение типа "Аудиосообщение".
*
* @author upagge [08/07/2019]
*/
public class AudioMessage extends Attachment {
/**
* Ссылка на аудиозапись в формате odd.
*/
private URL linkOdd;
public AudioMessage() {
type = AttachmentType.AUDIO_MESSAGE;
}
public AudioMessage(URL linkOdd) {
this.linkOdd = linkOdd;
}
}

View File

@ -1,69 +0,0 @@
package dev.struchkov.godfather.context.domain.content.attachment;
/**
* Вложение типа "Карта".
*
* @author upagge [08/07/2019]
*/
public class Geo extends Attachment {
/**
* Географические координаты.
*/
private GeoCoordinate geoCoordinate;
/**
* Название страны.
*/
private String country;
/**
* Название города.
*/
private String city;
private Geo() {
type = AttachmentType.GEO;
}
public static Builder builder() {
return new Geo().new Builder();
}
public GeoCoordinate getGeoCoordinate() {
return geoCoordinate;
}
public String getCountry() {
return country;
}
public String getCity() {
return city;
}
public class Builder {
private Builder() {
}
public Builder coordinate(Float lat, Float aLong) {
Geo.this.geoCoordinate = new GeoCoordinate(lat, aLong);
return this;
}
public Builder country(String countryName) {
Geo.this.country = countryName;
return this;
}
public Builder city(String cityName) {
Geo.this.city = cityName;
return this;
}
public Geo build() {
return Geo.this;
}
}
}

View File

@ -1,41 +0,0 @@
package dev.struchkov.godfather.context.domain.content.attachment;
/**
* Сущность для хранения географических координат.
*
* @author upagge [08/07/2019]
*/
public class GeoCoordinate {
/**
* Широта.
*/
private Float latitude;
/**
* Долгота.
*/
private Float longitude;
public GeoCoordinate(Float latitude, Float longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
public Float getLatitude() {
return latitude;
}
public void setLatitude(Float latitude) {
this.latitude = latitude;
}
public Float getLongitude() {
return longitude;
}
public void setLongitude(Float longitude) {
this.longitude = longitude;
}
}

View File

@ -1,19 +0,0 @@
package dev.struchkov.godfather.context.domain.content.attachment;
public class Link extends Attachment {
private String url;
public Link() {
this.type = AttachmentType.LINK;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

View File

@ -1,13 +1,15 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.service.Accessibility;
import dev.struchkov.godfather.context.service.usercode.CheckData; import dev.struchkov.godfather.context.service.usercode.CheckData;
import dev.struchkov.godfather.core.service.Accessibility;
import dev.struchkov.godfather.core.utils.TypeUnit;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static dev.struchkov.godfather.context.exception.UnitConfigException.unitConfigException; import static dev.struchkov.godfather.context.exception.UnitConfigException.unitConfigException;
import static dev.struchkov.haiti.utils.Inspector.isAnyNotNull; import static dev.struchkov.haiti.utils.Inspector.isAnyNotNull;
@ -71,7 +73,7 @@ public class AnswerCheck extends MainUnit {
public static final class Builder { public static final class Builder {
private String name; private String name;
private Set<String> keyWords = new HashSet<>(); private Set<KeyWord> keyWords = new HashSet<>();
private String phrase; private String phrase;
private Pattern pattern; private Pattern pattern;
private Integer matchThreshold; private Integer matchThreshold;
@ -90,13 +92,23 @@ public class AnswerCheck extends MainUnit {
return this; return this;
} }
public Builder keyWords(Set<String> val) { public Builder keyWords(Set<KeyWord> val) {
keyWords = val; keyWords.addAll(val);
return this;
}
public Builder keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public Builder stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this; return this;
} }
public Builder keyWord(String val) { public Builder keyWord(String val) {
keyWords.add(val); keyWords.add(KeyWord.of(val));
return this; return this;
} }

View File

@ -1,17 +1,19 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.context.service.Accessibility;
import dev.struchkov.godfather.core.service.save.CheckSave; import dev.struchkov.godfather.context.service.save.CheckSave;
import dev.struchkov.godfather.core.service.save.Preservable; import dev.struchkov.godfather.context.service.save.Preservable;
import dev.struchkov.godfather.core.service.save.data.PreservableData; import dev.struchkov.godfather.context.service.save.PreservableData;
import dev.struchkov.godfather.core.service.save.push.Pusher; import dev.struchkov.godfather.context.service.save.Pusher;
import dev.struchkov.godfather.core.utils.TypeUnit;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static dev.struchkov.haiti.utils.Inspector.isNotNull; import static dev.struchkov.haiti.utils.Inspector.isNotNull;
@ -107,7 +109,7 @@ public class AnswerSave<D> extends MainUnit {
public static final class Builder<D> { public static final class Builder<D> {
private String name; private String name;
private Set<String> keyWords = new HashSet<>(); private Set<KeyWord> keyWords = new HashSet<>();
private String phrase; private String phrase;
private Pattern pattern; private Pattern pattern;
private Integer matchThreshold; private Integer matchThreshold;
@ -129,13 +131,23 @@ public class AnswerSave<D> extends MainUnit {
return this; return this;
} }
public Builder<D> keyWords(Set<String> val) { public Builder<D> keyWords(Set<KeyWord> val) {
keyWords = val; keyWords.addAll(val);
return this;
}
public Builder<D> keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public Builder<D> stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this; return this;
} }
public Builder<D> keyWord(String val) { public Builder<D> keyWord(String val) {
keyWords.add(val); keyWords.add(KeyWord.of(val));
return this; return this;
} }

View File

@ -1,19 +1,21 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.context.domain.BoxAnswer; import dev.struchkov.godfather.context.domain.BoxAnswer;
import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.exception.UnitConfigException; import dev.struchkov.godfather.context.exception.UnitConfigException;
import dev.struchkov.godfather.context.service.Accessibility;
import dev.struchkov.godfather.context.service.sender.Sending; import dev.struchkov.godfather.context.service.sender.Sending;
import dev.struchkov.godfather.context.service.usercode.Insert; import dev.struchkov.godfather.context.service.usercode.Insert;
import dev.struchkov.godfather.context.service.usercode.MessageFunction; import dev.struchkov.godfather.context.service.usercode.MessageFunction;
import dev.struchkov.godfather.context.service.usercode.ProcessingData; import dev.struchkov.godfather.context.service.usercode.ProcessingData;
import dev.struchkov.godfather.core.service.Accessibility;
import dev.struchkov.godfather.core.utils.TypeUnit;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static dev.struchkov.haiti.utils.Inspector.isNotNull; import static dev.struchkov.haiti.utils.Inspector.isNotNull;
@ -82,7 +84,7 @@ public class AnswerText<M extends Message> extends MainUnit {
private ProcessingData<M> boxAnswer; private ProcessingData<M> boxAnswer;
private Insert insert; private Insert insert;
private Sending sending; private Sending sending;
private Set<String> keyWords = new HashSet<>(); private Set<KeyWord> keyWords = new HashSet<>();
private String phrase; private String phrase;
private Pattern pattern; private Pattern pattern;
private Integer matchThreshold; private Integer matchThreshold;
@ -135,8 +137,23 @@ public class AnswerText<M extends Message> extends MainUnit {
return this; return this;
} }
public Builder<M> keyWords(Set<String> val) { public Builder<M> keyWords(Set<KeyWord> val) {
keyWords = val; keyWords.addAll(val);
return this;
}
public Builder<M> keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public Builder<M> stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this;
}
public Builder<M> keyWord(String val) {
keyWords.add(KeyWord.of(val));
return this; return this;
} }

View File

@ -1,12 +1,16 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.keyboard.KeyBoard;
import dev.struchkov.godfather.context.service.Accessibility;
import dev.struchkov.godfather.context.service.usercode.CheckData; import dev.struchkov.godfather.context.service.usercode.CheckData;
import dev.struchkov.godfather.core.service.Accessibility;
import dev.struchkov.godfather.core.utils.TypeUnit;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static dev.struchkov.godfather.context.exception.UnitConfigException.unitConfigException; import static dev.struchkov.godfather.context.exception.UnitConfigException.unitConfigException;
import static dev.struchkov.haiti.utils.Inspector.isNotNull; import static dev.struchkov.haiti.utils.Inspector.isNotNull;
@ -83,7 +87,7 @@ public class AnswerTimer<M extends Message> extends MainUnit {
private Integer timeDelaySec; private Integer timeDelaySec;
private Integer timeDeathSec; private Integer timeDeathSec;
private CheckData<M> checkLoop; private CheckData<M> checkLoop;
private Set<String> keyWords; private Set<KeyWord> keyWords = new HashSet<>();
private String phrase; private String phrase;
private Pattern pattern; private Pattern pattern;
private Integer matchThreshold; private Integer matchThreshold;
@ -119,8 +123,23 @@ public class AnswerTimer<M extends Message> extends MainUnit {
return this; return this;
} }
public Builder<M> keyWords(Set<String> val) { public Builder<M> keyWords(Set<KeyWord> val) {
keyWords = val; keyWords.addAll(val);
return this;
}
public Builder<M> keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public Builder<M> stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this;
}
public Builder<M> keyWord(String val) {
keyWords.add(KeyWord.of(val));
return this; return this;
} }

View File

@ -1,14 +1,16 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.core.service.ClarificationQuestion; import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.core.service.save.LocalPreservable; import dev.struchkov.godfather.context.service.Accessibility;
import dev.struchkov.godfather.core.service.save.Preservable; import dev.struchkov.godfather.context.service.ClarificationQuestion;
import dev.struchkov.godfather.core.utils.TypeUnit; import dev.struchkov.godfather.context.service.save.LocalPreservable;
import dev.struchkov.godfather.context.service.save.Preservable;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* Обработка данных со страницы пользователя. * Обработка данных со страницы пользователя.
@ -85,7 +87,7 @@ public class AnswerValidity extends MainUnit {
private MainUnit unitNo; private MainUnit unitNo;
private MainUnit unitNull; private MainUnit unitNull;
private ClarificationQuestion clarificationQuestion; private ClarificationQuestion clarificationQuestion;
private Set<String> keyWords; private Set<KeyWord> keyWords = new HashSet<>();
private String phrase; private String phrase;
private Pattern pattern; private Pattern pattern;
private Integer matchThreshold; private Integer matchThreshold;
@ -121,13 +123,23 @@ public class AnswerValidity extends MainUnit {
return this; return this;
} }
public Builder keyWords(Set<String> val) { public Builder keyWords(Set<KeyWord> val) {
keyWords = val; keyWords.addAll(val);
return this;
}
public Builder keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public Builder stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this; return this;
} }
public Builder keyWord(String val) { public Builder keyWord(String val) {
keyWords.add(val); keyWords.add(KeyWord.of(val));
return this; return this;
} }
@ -162,7 +174,7 @@ public class AnswerValidity extends MainUnit {
} }
public Builder clearKeyWords() { public Builder clearKeyWords() {
nextUnits.clear(); keyWords.clear();
return this; return this;
} }

View File

@ -1,7 +1,9 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.context.domain.UnitDefinition; import dev.struchkov.godfather.context.domain.UnitDefinition;
import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.context.domain.keyboard.KeyBoard;
import dev.struchkov.godfather.context.service.Accessibility;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -12,7 +14,7 @@ public class LazyUnit extends MainUnit {
private LazyUnit( private LazyUnit(
String name, String name,
Set<String> keyWords, Set<KeyWord> keyWords,
String phrase, String phrase,
Pattern pattern, Pattern pattern,
Integer matchThreshold, Integer matchThreshold,

View File

@ -1,7 +1,8 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.autoresponder.entity.Unit; import dev.struchkov.autoresponder.entity.Unit;
import dev.struchkov.godfather.core.service.Accessibility; import dev.struchkov.godfather.context.service.Accessibility;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@ -43,7 +44,7 @@ public abstract class MainUnit extends Unit<MainUnit> {
protected MainUnit( protected MainUnit(
String name, String name,
Set<String> keyWords, Set<KeyWord> keyWords,
String phrase, String phrase,
Pattern pattern, Pattern pattern,
Integer matchThreshold, Integer matchThreshold,

View File

@ -1,4 +1,4 @@
package dev.struchkov.godfather.core.domain.unit; package dev.struchkov.godfather.context.domain.unit;
/** /**
* Тип активации Unit-а. Определяет порядок обработки Unit. * Тип активации Unit-а. Определяет порядок обработки Unit.

View File

@ -0,0 +1,133 @@
package dev.struchkov.godfather.context.domain.unit.cmd;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.domain.unit.UnitActiveType;
import dev.struchkov.godfather.context.exception.UnitConfigException;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Юнит, который позволяет откатить пользователя на предыдущие юниты в сценарии с сохранением ранее введенной информации в сообщениях.
*/
public class RollBackCmd extends MainUnit {
/**
* Количество юнитов, на которые можно откатиться назад.
*/
private final int countBack;
private RollBackCmd(Builder builder) {
super(
builder.name,
builder.keyWords,
builder.phrase,
builder.pattern,
builder.matchThreshold,
builder.priority,
new HashSet<>(),
builder.activeType,
null,
TypeUnit.BACK_CMD
);
this.countBack = builder.countBack;
}
public int getCountBack() {
return countBack;
}
public static RollBackCmd.Builder builder() {
return new RollBackCmd.Builder();
}
public static RollBackCmd rollBack(int countToBack) {
return RollBackCmd.builder().countBack(countToBack).build();
}
public static RollBackCmd singleRollBack() {
return RollBackCmd.builder().countBack(1).build();
}
public static final class Builder {
private String name;
private Set<KeyWord> keyWords = new HashSet<>();
private String phrase;
private Pattern pattern;
private Integer matchThreshold;
private Integer priority;
private UnitActiveType activeType = UnitActiveType.DEFAULT;
private int countBack;
private Builder() {
}
public RollBackCmd.Builder name(String name) {
this.name = name;
return this;
}
public RollBackCmd.Builder keyWords(Set<KeyWord> val) {
keyWords.addAll(val);
return this;
}
public RollBackCmd.Builder keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public RollBackCmd.Builder stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this;
}
public RollBackCmd.Builder keyWord(String val) {
keyWords.add(KeyWord.of(val));
return this;
}
public RollBackCmd.Builder phrase(String val) {
phrase = val;
return this;
}
public RollBackCmd.Builder pattern(Pattern val) {
pattern = val;
return this;
}
public RollBackCmd.Builder matchThreshold(Integer val) {
matchThreshold = val;
return this;
}
public RollBackCmd.Builder priority(Integer val) {
priority = val;
return this;
}
public RollBackCmd.Builder activeType(UnitActiveType val) {
activeType = val;
return this;
}
public RollBackCmd.Builder countBack(int val) {
countBack = val + 1;
return this;
}
public RollBackCmd build() {
if (countBack < 2) {
throw new UnitConfigException("Ошибка конфигурирования юнита {0}: Количество юнитов для отката не должно быть меньше 1.", name);
}
return new RollBackCmd(this);
}
}
}

View File

@ -0,0 +1,121 @@
package dev.struchkov.godfather.context.domain.unit.cmd;
import dev.struchkov.autoresponder.entity.KeyWord;
import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.domain.unit.UnitActiveType;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Позволяет перенести пользователя в произвольное место в сценарии.
*/
public class TeleportCmd extends MainUnit {
/**
* Название юнита, в которое необходимо осуществить перенос.
*/
private String unitNameToTeleport;
private TeleportCmd(Builder builder) {
super(
builder.name,
builder.keyWords,
builder.phrase,
builder.pattern,
builder.matchThreshold,
builder.priority,
new HashSet<>(),
builder.activeType,
null,
TypeUnit.TELEPORT_CMD
);
this.unitNameToTeleport = builder.unitNameToTeleport;
}
public String getUnitNameToTeleport() {
return unitNameToTeleport;
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private String name;
private Set<KeyWord> keyWords = new HashSet<>();
private String phrase;
private Pattern pattern;
private Integer matchThreshold;
private Integer priority;
private UnitActiveType activeType = UnitActiveType.DEFAULT;
private String unitNameToTeleport;
private Builder() {
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder keyWords(Set<KeyWord> val) {
keyWords.addAll(val);
return this;
}
public Builder keyWord(KeyWord val) {
keyWords.add(val);
return this;
}
public Builder stringKeyWords(Set<String> val) {
keyWords.addAll(val.stream().map(KeyWord::of).collect(Collectors.toSet()));
return this;
}
public Builder keyWord(String val) {
keyWords.add(KeyWord.of(val));
return this;
}
public Builder phrase(String val) {
phrase = val;
return this;
}
public Builder pattern(Pattern val) {
pattern = val;
return this;
}
public Builder matchThreshold(Integer val) {
matchThreshold = val;
return this;
}
public Builder priority(Integer val) {
priority = val;
return this;
}
public Builder activeType(UnitActiveType val) {
activeType = val;
return this;
}
public Builder unitNameToTeleport(String val) {
unitNameToTeleport = val;
return this;
}
public TeleportCmd build() {
return new TeleportCmd(this);
}
}
}

View File

@ -0,0 +1,16 @@
package dev.struchkov.godfather.context.repository;
import dev.struchkov.godfather.context.domain.StorylineHistory;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public interface StorylineRepository {
void save(@NotNull StorylineHistory storylineHistory);
Optional<StorylineHistory> findByCountLast(long personId, int countUnitsToBack);
void cleanHistoryByPersonId(@NotNull Long personId);
}

View File

@ -0,0 +1,47 @@
package dev.struchkov.godfather.context.repository.impl.local;
import dev.struchkov.godfather.context.domain.StorylineHistory;
import dev.struchkov.godfather.context.repository.StorylineRepository;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Stack;
public class StorylineMapRepository implements StorylineRepository {
private final Map<Long, Stack<StorylineHistory>> map = new HashMap<>();
@Override
public void save(@NotNull StorylineHistory history) {
final Long personId = history.getPersonId();
map.computeIfAbsent(personId, k -> new Stack<>()).push(history);
}
@Override
public Optional<StorylineHistory> findByCountLast(long personId, int countUnitsToBack) {
if (map.containsKey(personId)) {
final Stack<StorylineHistory> stack = map.get(personId);
if (stack.size() < countUnitsToBack) {
countUnitsToBack = stack.size();
}
StorylineHistory storylineHistory = null;
for (int i = 0; i < countUnitsToBack; i++) {
storylineHistory = stack.pop();
}
return Optional.ofNullable(storylineHistory);
}
return Optional.empty();
}
@Override
public void cleanHistoryByPersonId(@NotNull Long personId) {
if (map.containsKey(personId)) {
map.get(personId).clear();
} else {
map.put(personId, new Stack<>());
}
}
}

View File

@ -10,7 +10,7 @@ import java.util.Optional;
public class UnitPointLocalRepository implements UnitPointerRepository { public class UnitPointLocalRepository implements UnitPointerRepository {
public static final Map<Long, String> map = new HashMap<>(); public final Map<Long, String> map = new HashMap<>();
@Override @Override
public UnitPointer save(@NotNull UnitPointer unitPointer) { public UnitPointer save(@NotNull UnitPointer unitPointer) {

View File

@ -1,4 +1,4 @@
package dev.struchkov.godfather.core.service; package dev.struchkov.godfather.context.service;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;

View File

@ -1,7 +1,7 @@
package dev.struchkov.godfather.core.service; package dev.struchkov.godfather.context.service;
import dev.struchkov.godfather.context.domain.Clarification;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.core.domain.Clarification;
@FunctionalInterface @FunctionalInterface
public interface ClarificationQuestion<C extends Message> { public interface ClarificationQuestion<C extends Message> {

View File

@ -0,0 +1,35 @@
package dev.struchkov.godfather.context.service;
import dev.struchkov.godfather.context.domain.StorylineHistory;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
import java.util.Set;
public interface StorylineService<T extends Message> {
void save(@NotNull StorylineHistory storylineHistory);
Optional<MainUnit> getUnitNameByPersonId(@NotNull Long personId);
Set<MainUnit> getNextUnitByPersonId(@NotNull Long personId);
void save(Long personId, String name, T message);
Optional<StorylineHistory> replaceUserToBack(long personId, int countUnitsToBack);
Optional<MainUnit> getDefaultUnit();
/**
* Ленивая (поздняя) связка юнитов между собой. Осуществляется уже после создания сценария. С помощью данного подхода можно реализовать циклические зависимости юнитов. Либо можно использовать {@link dev.struchkov.godfather.context.domain.unit.cmd.TeleportCmd}
*
* @param firstName
* @param secondName
*/
void lazyLink(String firstName, String secondName);
Optional<MainUnit> getUnitByName(String unitName);
}

View File

@ -1,7 +1,7 @@
package dev.struchkov.godfather.core.service.save; package dev.struchkov.godfather.context.service.save;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
/** /**
* TODO: Добавить описание интерфейса. * TODO: Добавить описание интерфейса.

View File

@ -1,4 +1,6 @@
package dev.struchkov.godfather.core.service.save; package dev.struchkov.godfather.context.service.save;
import dev.struchkov.godfather.context.service.save.Preservable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;

View File

@ -1,6 +1,6 @@
package dev.struchkov.godfather.core.service.save; package dev.struchkov.godfather.context.service.save;
import dev.struchkov.godfather.core.service.save.push.Pusher; import dev.struchkov.godfather.context.service.save.Pusher;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;

View File

@ -1,4 +1,4 @@
package dev.struchkov.godfather.core.service.save.data; package dev.struchkov.godfather.context.service.save;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;

View File

@ -1,4 +1,4 @@
package dev.struchkov.godfather.core.service.save.push; package dev.struchkov.godfather.context.service.save;
import java.util.Map; import java.util.Map;

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>dev.struchkov.godfather</groupId> <groupId>dev.struchkov.godfather</groupId>
<artifactId>godfather-bot</artifactId> <artifactId>godfather-bot</artifactId>
<version>0.0.8</version> <version>0.0.9</version>
</parent> </parent>
<artifactId>bot-core</artifactId> <artifactId>bot-core</artifactId>
@ -19,11 +19,6 @@
<groupId>dev.struchkov.godfather</groupId> <groupId>dev.struchkov.godfather</groupId>
<artifactId>bot-context</artifactId> <artifactId>bot-context</artifactId>
</dependency> </dependency>
<dependency>
<groupId>dev.struchkov</groupId>
<artifactId>autoresponder</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,27 +1,25 @@
package dev.struchkov.godfather.core; package dev.struchkov.godfather.core;
import dev.struchkov.autoresponder.Responder; import dev.struchkov.autoresponder.Responder;
import dev.struchkov.autoresponder.entity.Unit; import dev.struchkov.godfather.context.domain.TypeUnit;
import dev.struchkov.godfather.context.domain.UnitPointer; import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.domain.unit.UnitActiveType;
import dev.struchkov.godfather.context.exception.ConfigAppException; import dev.struchkov.godfather.context.exception.ConfigAppException;
import dev.struchkov.godfather.context.service.Accessibility;
import dev.struchkov.godfather.context.service.Modifiable; import dev.struchkov.godfather.context.service.Modifiable;
import dev.struchkov.godfather.context.service.PersonSettingService; import dev.struchkov.godfather.context.service.PersonSettingService;
import dev.struchkov.godfather.context.service.UnitPointerService; import dev.struchkov.godfather.context.service.StorylineService;
import dev.struchkov.godfather.context.service.sender.Sending; import dev.struchkov.godfather.context.service.sender.Sending;
import dev.struchkov.godfather.core.domain.unit.MainUnit;
import dev.struchkov.godfather.core.domain.unit.UnitActiveType;
import dev.struchkov.godfather.core.service.Accessibility;
import dev.struchkov.godfather.core.service.ErrorHandler; import dev.struchkov.godfather.core.service.ErrorHandler;
import dev.struchkov.godfather.core.service.action.ActionUnit; import dev.struchkov.godfather.core.service.action.ActionUnit;
import dev.struchkov.godfather.core.service.action.AnswerCheckAction; import dev.struchkov.godfather.core.service.action.AnswerCheckAction;
import dev.struchkov.godfather.core.service.action.AnswerProcessingAction;
import dev.struchkov.godfather.core.service.action.AnswerSaveAction; import dev.struchkov.godfather.core.service.action.AnswerSaveAction;
import dev.struchkov.godfather.core.service.action.AnswerTextAction; import dev.struchkov.godfather.core.service.action.AnswerTextAction;
import dev.struchkov.godfather.core.service.action.AnswerTimerAction; import dev.struchkov.godfather.core.service.action.AnswerTimerAction;
import dev.struchkov.godfather.core.service.action.AnswerValidityAction; import dev.struchkov.godfather.core.service.action.AnswerValidityAction;
import dev.struchkov.godfather.core.service.timer.TimerService; import dev.struchkov.godfather.core.service.timer.TimerService;
import dev.struchkov.godfather.core.utils.TypeUnit;
import dev.struchkov.haiti.context.exception.NotFoundException; import dev.struchkov.haiti.context.exception.NotFoundException;
import java.util.HashMap; import java.util.HashMap;
@ -33,10 +31,10 @@ import java.util.stream.Collectors;
public class GeneralAutoResponder<T extends Message> { public class GeneralAutoResponder<T extends Message> {
private ErrorHandler errorHandler;
private final PersonSettingService personSettingService; private final PersonSettingService personSettingService;
private final UnitPointerService unitPointerService;
private final StoryLine storyLine; private ErrorHandler errorHandler;
private final StorylineService<T> storyLineService;
protected Map<String, ActionUnit<? extends MainUnit, ? extends Message>> actionUnitMap = new HashMap<>(); protected Map<String, ActionUnit<? extends MainUnit, ? extends Message>> actionUnitMap = new HashMap<>();
protected List<Modifiable<T>> modifiable; protected List<Modifiable<T>> modifiable;
@ -44,18 +42,15 @@ public class GeneralAutoResponder<T extends Message> {
protected GeneralAutoResponder( protected GeneralAutoResponder(
Sending sending, Sending sending,
PersonSettingService personSettingService, PersonSettingService personSettingService,
UnitPointerService unitPointerService, StorylineService<T> storyLineService
List<Object> unitConfigurations
) { ) {
this.personSettingService = personSettingService; this.personSettingService = personSettingService;
this.unitPointerService = unitPointerService; this.storyLineService = storyLineService;
this.storyLine = new StorylineMaker(unitConfigurations).createStoryLine();
init(sending); init(sending);
} }
private void init(Sending sending) { private void init(Sending sending) {
actionUnitMap.put(TypeUnit.CHECK, new AnswerCheckAction()); actionUnitMap.put(TypeUnit.CHECK, new AnswerCheckAction());
actionUnitMap.put(TypeUnit.PROCESSING, new AnswerProcessingAction(sending));
actionUnitMap.put(TypeUnit.TEXT, new AnswerTextAction(sending)); actionUnitMap.put(TypeUnit.TEXT, new AnswerTextAction(sending));
actionUnitMap.put(TypeUnit.VALIDITY, new AnswerValidityAction()); actionUnitMap.put(TypeUnit.VALIDITY, new AnswerValidityAction());
} }
@ -64,7 +59,7 @@ public class GeneralAutoResponder<T extends Message> {
this.modifiable = modifiable; this.modifiable = modifiable;
} }
public void initActionUnit(String typeUnit, ActionUnit<? super MainUnit, T> actionUnit) { public void initActionUnit(String typeUnit, ActionUnit<? extends MainUnit, T> actionUnit) {
if (!actionUnitMap.containsKey(typeUnit)) { if (!actionUnitMap.containsKey(typeUnit)) {
actionUnitMap.put(typeUnit, actionUnit); actionUnitMap.put(typeUnit, actionUnit);
} else { } else {
@ -113,16 +108,12 @@ public class GeneralAutoResponder<T extends Message> {
if (modifiable != null) { if (modifiable != null) {
modifiable.forEach(m -> m.change(message)); modifiable.forEach(m -> m.change(message));
} }
final Set<MainUnit> units = unitPointerService.getUnitNameByPersonId(message.getPersonId()) final Set<MainUnit> units = storyLineService.getNextUnitByPersonId(message.getPersonId());
.flatMap(storyLine::getUnit)
.map(Unit::getNextUnits)
.filter(mainUnits -> !mainUnits.isEmpty())
.orElse(storyLine.getStartingUnits());
final Optional<MainUnit> optAnswer = Responder.nextUnit(message.getText(), units); final Optional<MainUnit> optAnswer = Responder.nextUnit(message.getText(), units);
if (optAnswer.isPresent()) { if (optAnswer.isPresent()) {
final MainUnit answer = optAnswer.get(); final MainUnit answer = optAnswer.get();
if (checkPermission(answer.getAccessibility(), message)) { if (checkPermission(answer.getAccessibility(), message)) {
answer(message, answer); answer(UnitRequest.of(answer, message));
} }
} }
} }
@ -131,50 +122,51 @@ public class GeneralAutoResponder<T extends Message> {
return accessibility.isEmpty() || accessibility.get().check(message); return accessibility.isEmpty() || accessibility.get().check(message);
} }
public void answer(T message, MainUnit unitAnswer) { public void answer(UnitRequest<MainUnit, T> unitRequest) {
try { try {
unitAnswer = getAction(message, unitAnswer); unitRequest = getAction(unitRequest);
unitAnswer = activeUnitAfter(unitAnswer, message); unitRequest = activeUnitAfter(unitRequest);
final Optional<MainUnit> optDefaultUnit = storyLine.getDefaultUnit(); final Optional<MainUnit> optDefaultUnit = storyLineService.getDefaultUnit();
if (optDefaultUnit.isEmpty() || !optDefaultUnit.get().equals(unitAnswer)) { final MainUnit unit = unitRequest.getUnit();
unitPointerService.save(new UnitPointer(message.getPersonId(), unitAnswer.getName())); final T message = unitRequest.getMessage();
if (optDefaultUnit.isEmpty() || !optDefaultUnit.get().equals(unit)) {
storyLineService.save(message.getPersonId(), unit.getName(), message);
} }
} catch (Exception e) { } catch (Exception e) {
if (errorHandler != null) { if (errorHandler != null) {
errorHandler.handle(message, e); errorHandler.handle(unitRequest.getMessage(), e);
} else { } else {
throw e; throw e;
} }
} }
} }
private MainUnit activeUnitAfter(MainUnit mainUnit, T content) { private UnitRequest<MainUnit, T> activeUnitAfter(UnitRequest<MainUnit, T> unitRequest) {
if (mainUnit.getNextUnits() != null) { final Set<MainUnit> nextUnits = unitRequest.getUnit().getNextUnits();
Optional<MainUnit> first = mainUnit.getNextUnits().stream() if (nextUnits != null) {
Optional<MainUnit> first = nextUnits.stream()
.filter(unit -> UnitActiveType.AFTER.equals(unit.getActiveType())) .filter(unit -> UnitActiveType.AFTER.equals(unit.getActiveType()))
.findFirst(); .findFirst();
if (first.isPresent()) { if (first.isPresent()) {
getAction(content, first.get()); getAction(UnitRequest.of(first.get(), unitRequest.getMessage()));
return activeUnitAfter(first.get(), content); return activeUnitAfter(UnitRequest.of(first.get(), unitRequest.getMessage()));
} }
} }
return mainUnit; return unitRequest;
} }
private MainUnit getAction(T event, MainUnit unitAnswer) { private UnitRequest<MainUnit, T> getAction(UnitRequest<MainUnit, T> unitRequest) {
if (actionUnitMap.containsKey(unitAnswer.getType())) { final MainUnit unit = unitRequest.getUnit();
ActionUnit actionUnit = actionUnitMap.get(unitAnswer.getType()); final String typeUnit = unit.getType();
MainUnit mainUnit = actionUnit.action(unitAnswer, event); if (actionUnitMap.containsKey(typeUnit)) {
return !unitAnswer.equals(mainUnit) ? getAction(event, mainUnit) : mainUnit; ActionUnit actionUnit = actionUnitMap.get(typeUnit);
UnitRequest<MainUnit, T> newUnitRequest = actionUnit.action(unitRequest);
final MainUnit newUnit = newUnitRequest.getUnit();
return !unit.equals(newUnit) ? getAction(newUnitRequest) : unitRequest;
} else { } else {
throw new NotFoundException("ActionUnit для типа {0} не зарегистрирован", unitAnswer.getType()); throw new NotFoundException("ActionUnit для типа {0} не зарегистрирован", unit.getType());
} }
} }
//TODO [22.06.2022]: Временное решение для ленивой инициализации
public void link(String firstName, String secondName) {
storyLine.link(firstName, secondName);
}
} }

View File

@ -1,6 +1,6 @@
package dev.struchkov.godfather.core; package dev.struchkov.godfather.core;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.haiti.utils.Inspector; import dev.struchkov.haiti.utils.Inspector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -10,13 +10,13 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
public class StoryLine { public class Storyline {
private MainUnit defaultUnit; private MainUnit defaultUnit;
private final Set<MainUnit> startingUnits = new HashSet<>(); private final Set<MainUnit> startingUnits = new HashSet<>();
private final Map<String, MainUnit> units = new HashMap<>(); private final Map<String, MainUnit> units = new HashMap<>();
public StoryLine(Set<MainUnit> startingUnits, Map<String, MainUnit> units) { public Storyline(Set<MainUnit> startingUnits, Map<String, MainUnit> units) {
this.startingUnits.addAll(startingUnits); this.startingUnits.addAll(startingUnits);
this.units.putAll(units); this.units.putAll(units);
} }

View File

@ -3,8 +3,8 @@ package dev.struchkov.godfather.core;
import dev.struchkov.godfather.context.domain.UnitDefinition; import dev.struchkov.godfather.context.domain.UnitDefinition;
import dev.struchkov.godfather.context.domain.annotation.Unit; import dev.struchkov.godfather.context.domain.annotation.Unit;
import dev.struchkov.godfather.context.exception.UnitConfigException; import dev.struchkov.godfather.context.exception.UnitConfigException;
import dev.struchkov.godfather.core.domain.unit.LazyUnit; import dev.struchkov.godfather.context.domain.unit.LazyUnit;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.haiti.utils.Inspector; import dev.struchkov.haiti.utils.Inspector;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -46,13 +46,13 @@ public class StorylineMaker {
return unitMap; return unitMap;
} }
public StoryLine createStoryLine() { public Storyline createStoryLine() {
generateUnitDefinitions(); generateUnitDefinitions();
try { try {
createUnitMap(); createUnitMap();
createLazy(); createLazy();
final Set<MainUnit> mainUnit = getMainUnit(); final Set<MainUnit> mainUnit = getMainUnit();
return new StoryLine(mainUnit, unitMap); return new Storyline(mainUnit, unitMap);
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }

View File

@ -1,7 +1,7 @@
package dev.struchkov.godfather.core.domain; package dev.struchkov.godfather.core.domain;
import dev.struchkov.godfather.context.service.usercode.CheckData; import dev.struchkov.godfather.context.service.usercode.CheckData;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
import java.time.LocalDateTime; import java.time.LocalDateTime;

View File

@ -1,146 +0,0 @@
package dev.struchkov.godfather.core.domain.unit;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.service.sender.Sending;
import dev.struchkov.godfather.context.service.usercode.ProcessingData;
import dev.struchkov.godfather.core.service.Accessibility;
import dev.struchkov.godfather.core.utils.TypeUnit;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Обработчик для кастомных реализаций.
*
* @author upagge [08/07/2019]
*/
public class AnswerProcessing<M extends Message> extends MainUnit {
/**
* Кастомная обработка.
*/
private final ProcessingData<M> processingData;
/**
* Объект для сквозной отправки ответа.
*/
private final Sending sending;
private AnswerProcessing(Builder<M> builder) {
super(
builder.name,
builder.keyWords,
builder.phrase,
builder.pattern,
builder.matchThreshold,
builder.priority,
builder.nextUnits,
builder.activeType,
builder.accessibility,
TypeUnit.PROCESSING
);
processingData = builder.processingData;
sending = builder.sending;
}
public static <M extends Message> Builder<M> builder() {
return new Builder<>();
}
public ProcessingData<M> getProcessingData() {
return processingData;
}
public Sending getSending() {
return sending;
}
public static final class Builder<M extends Message> {
private String name;
private Set<String> keyWords = new HashSet<>();
private String phrase;
private Pattern pattern;
private Integer matchThreshold;
private Integer priority;
private Set<MainUnit> nextUnits = new HashSet<>();
private ProcessingData<M> processingData;
private Sending sending;
private UnitActiveType activeType;
private Accessibility accessibility;
private Builder() {
}
public Builder<M> name(String name) {
this.name = name;
return this;
}
public Builder<M> processingData(ProcessingData<M> val) {
processingData = val;
return this;
}
public Builder<M> sending(Sending val) {
sending = val;
return this;
}
public Builder<M> keyWords(Set<String> val) {
keyWords = val;
return this;
}
public Builder<M> keyWord(String val) {
keyWords.add(val);
return this;
}
public Builder<M> phrase(String val) {
phrase = val;
return this;
}
public Builder<M> pattern(Pattern val) {
pattern = val;
return this;
}
public Builder<M> matchThreshold(Integer val) {
matchThreshold = val;
return this;
}
public Builder<M> priority(Integer val) {
priority = val;
return this;
}
public Builder<M> nextUnits(Set<MainUnit> val) {
nextUnits = val;
return this;
}
public Builder<M> nextUnit(MainUnit val) {
nextUnits.add(val);
return this;
}
public Builder accessibility(Accessibility val) {
accessibility = val;
return this;
}
public Builder<M> activeType(UnitActiveType val) {
activeType = val;
return this;
}
public AnswerProcessing<M> build() {
return new AnswerProcessing<>(this);
}
}
}

View File

@ -0,0 +1,100 @@
package dev.struchkov.godfather.core.service;
import dev.struchkov.autoresponder.entity.Unit;
import dev.struchkov.godfather.context.domain.StorylineHistory;
import dev.struchkov.godfather.context.domain.UnitPointer;
import dev.struchkov.godfather.context.domain.content.Mail;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.repository.StorylineRepository;
import dev.struchkov.godfather.context.service.StorylineService;
import dev.struchkov.godfather.context.service.UnitPointerService;
import dev.struchkov.godfather.core.Storyline;
import dev.struchkov.godfather.core.StorylineMaker;
import dev.struchkov.haiti.utils.Inspector;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import static dev.struchkov.haiti.utils.Inspector.isNotNull;
/**
* Отвечает за работу со сценарием в личных сообщениях с пользователем.
*/
public class StorylineMailService implements StorylineService<Mail> {
private final UnitPointerService unitPointerService;
private final StorylineRepository storylineRepository;
private final Storyline storyLine;
public StorylineMailService(
UnitPointerService unitPointerService,
StorylineRepository storylineRepository,
List<Object> unitConfigurations
) {
this.storyLine = new StorylineMaker(unitConfigurations).createStoryLine();
this.unitPointerService = unitPointerService;
this.storylineRepository = storylineRepository;
}
@Override
public void save(@NotNull StorylineHistory storylineHistory) {
isNotNull(storylineHistory);
storylineHistory.setId(null);
storylineRepository.save(storylineHistory);
}
@Override
public Optional<MainUnit> getUnitNameByPersonId(@NotNull Long personId) {
Inspector.isNotNull(personId);
return unitPointerService.getUnitNameByPersonId(personId)
.flatMap(storyLine::getUnit);
}
@Override
public Set<MainUnit> getNextUnitByPersonId(@NotNull Long personId) {
final Optional<Set<MainUnit>> optMainUnits = getUnitNameByPersonId(personId)
.map(Unit::getNextUnits)
.filter(mainUnits -> !mainUnits.isEmpty());
if (optMainUnits.isEmpty()) {
storylineRepository.cleanHistoryByPersonId(personId);
}
return optMainUnits
.orElse(storyLine.getStartingUnits());
}
@Override
public void save(Long personId, String unitName, Mail mail) {
Inspector.isNotNull(personId, unitName, mail);
unitPointerService.save(new UnitPointer(personId, unitName));
final StorylineHistory storylineHistory = new StorylineHistory();
storylineHistory.setPersonId(personId);
storylineHistory.setUnitName(unitName);
storylineHistory.setMessage(mail);
storylineRepository.save(storylineHistory);
}
@Override
public Optional<StorylineHistory> replaceUserToBack(long personId, int countUnitsToBack) {
return storylineRepository.findByCountLast(personId, countUnitsToBack);
}
@Override
public Optional<MainUnit> getDefaultUnit() {
return storyLine.getDefaultUnit();
}
//TODO [22.06.2022]: Временное решение для ленивой инициализации
@Override
public void lazyLink(String firstName, String secondName) {
storyLine.link(firstName, secondName);
}
@Override
public Optional<MainUnit> getUnitByName(String unitName) {
return storyLine.getUnit(unitName);
}
}

View File

@ -1,7 +1,8 @@
package dev.struchkov.godfather.core.service.action; package dev.struchkov.godfather.core.service.action;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
/** /**
* Интерфейс для обработки Unit-ов. * Интерфейс для обработки Unit-ов.
@ -14,10 +15,8 @@ public interface ActionUnit<M extends MainUnit, C extends Message> {
/** /**
* Метод обработки Unit-а. * Метод обработки Unit-а.
* *
* @param unit Unit, который необходимо обработать
* @param content Запрос пользователя
* @return Новый Unit, который может нуждаться в обработке * @return Новый Unit, который может нуждаться в обработке
*/ */
MainUnit action(M unit, C content); UnitRequest<MainUnit, C> action(UnitRequest<M, C> unitRequest);
} }

View File

@ -1,11 +1,13 @@
package dev.struchkov.godfather.core.service.action; package dev.struchkov.godfather.core.service.action;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.core.domain.unit.AnswerCheck; import dev.struchkov.godfather.context.domain.unit.AnswerCheck;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
/** /**
@ -18,16 +20,18 @@ public class AnswerCheckAction implements ActionUnit<AnswerCheck, Message> {
private static final Logger log = LoggerFactory.getLogger(AnswerCheckAction.class); private static final Logger log = LoggerFactory.getLogger(AnswerCheckAction.class);
@Override @Override
public MainUnit action(AnswerCheck answerCheck, Message mail) { public UnitRequest<MainUnit, Message> action(UnitRequest<AnswerCheck, Message> unitRequest) {
final AnswerCheck unit = unitRequest.getUnit();
final Message message = unitRequest.getMessage();
MainUnit unitAnswer; MainUnit unitAnswer;
if (answerCheck.getCheck().checked(mail)) { if (unit.getCheck().checked(message)) {
log.info("Проверка пройдена"); log.info("Проверка пройдена");
unitAnswer = answerCheck.getUnitTrue(); unitAnswer = unit.getUnitTrue();
} else { } else {
log.info("Проверка не пройдена"); log.info("Проверка не пройдена");
unitAnswer = answerCheck.getUnitFalse(); unitAnswer = unit.getUnitFalse();
} }
return Optional.ofNullable(unitAnswer).orElse(answerCheck); return UnitRequest.of(Objects.requireNonNullElse(unitAnswer, unit), message);
} }
} }

View File

@ -1,36 +0,0 @@
package dev.struchkov.godfather.core.service.action;
import dev.struchkov.godfather.context.domain.BoxAnswer;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.service.sender.Sending;
import dev.struchkov.godfather.context.utils.Sender;
import dev.struchkov.godfather.core.domain.unit.AnswerProcessing;
import dev.struchkov.godfather.core.domain.unit.MainUnit;
/**
* Обработчик Unit-а {@link AnswerProcessing}.
*
* @author upagge [11/07/2019]
*/
public class AnswerProcessingAction implements ActionUnit<AnswerProcessing<Message>, Message> {
private final Sending sending;
public AnswerProcessingAction(Sending sending) {
this.sending = sending;
}
@Override
public MainUnit action(AnswerProcessing<Message> answerProcessing, Message message) {
final BoxAnswer boxAnswer = answerProcessing.getProcessingData().processing(message);
Sending answerProcessingSending = answerProcessing.getSending();
if (answerProcessingSending != null) {
Sender.sends(message, boxAnswer, answerProcessingSending);
} else {
Sender.sends(message, boxAnswer, this.sending);
}
return answerProcessing;
}
}

View File

@ -1,11 +1,12 @@
package dev.struchkov.godfather.core.service.action; package dev.struchkov.godfather.core.service.action;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.core.domain.unit.AnswerSave; import dev.struchkov.godfather.context.domain.unit.AnswerSave;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.core.service.save.CheckSave; import dev.struchkov.godfather.context.service.save.CheckSave;
import dev.struchkov.godfather.core.service.save.Preservable; import dev.struchkov.godfather.context.service.save.Preservable;
import dev.struchkov.godfather.core.service.save.data.PreservableData; import dev.struchkov.godfather.context.service.save.PreservableData;
/** /**
* Обработчик Unit-а {@link AnswerSave}. * Обработчик Unit-а {@link AnswerSave}.
@ -15,27 +16,30 @@ import dev.struchkov.godfather.core.service.save.data.PreservableData;
public class AnswerSaveAction<D> implements ActionUnit<AnswerSave<D>, Message> { public class AnswerSaveAction<D> implements ActionUnit<AnswerSave<D>, Message> {
@Override @Override
public MainUnit action(AnswerSave<D> answerSave, Message mail) { public UnitRequest<MainUnit, Message> action(UnitRequest<AnswerSave<D>, Message> unitRequest) {
Preservable<D> preservable = answerSave.getPreservable(); final AnswerSave<D> answerSave = unitRequest.getUnit();
Long personId = mail.getPersonId(); final Message message = unitRequest.getMessage();
CheckSave<? super Message> checkSave = answerSave.getCheckSave(); final Preservable<D> preservable = answerSave.getPreservable();
final Long personId = message.getPersonId();
final CheckSave<? super Message> checkSave = answerSave.getCheckSave();
if (checkSave != null) { if (checkSave != null) {
MainUnit unit = checkSave.check(mail); MainUnit unit = checkSave.check(message);
if (unit != null) { if (unit != null) {
return unit; return UnitRequest.of(unit, message);
} }
} }
PreservableData<D, ? super Message> preservableData = answerSave.getPreservableData(); PreservableData<D, ? super Message> preservableData = answerSave.getPreservableData();
if (preservableData != null) { if (preservableData != null) {
D data = preservableData.getData(mail); D data = preservableData.getData(message);
if (data != null) { if (data != null) {
preservable.save(personId, answerSave.getKey(), data); preservable.save(personId, answerSave.getKey(), data);
} }
} }
preservable.push(personId, answerSave.getPusher()); preservable.push(personId, answerSave.getPusher());
return answerSave; return UnitRequest.of(answerSave, message);
} }
} }

View File

@ -1,12 +1,13 @@
package dev.struchkov.godfather.core.service.action; package dev.struchkov.godfather.core.service.action;
import dev.struchkov.godfather.context.domain.BoxAnswer; import dev.struchkov.godfather.context.domain.BoxAnswer;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.AnswerText;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.service.sender.Sending; import dev.struchkov.godfather.context.service.sender.Sending;
import dev.struchkov.godfather.context.utils.InsertWords; import dev.struchkov.godfather.context.utils.InsertWords;
import dev.struchkov.godfather.context.utils.Sender; import dev.struchkov.godfather.context.utils.Sender;
import dev.struchkov.godfather.core.domain.unit.AnswerText;
import dev.struchkov.godfather.core.domain.unit.MainUnit;
import java.util.List; import java.util.List;
@ -24,18 +25,21 @@ public class AnswerTextAction implements ActionUnit<AnswerText<Message>, Message
} }
@Override @Override
public MainUnit action(AnswerText<Message> answerText, Message message) { public UnitRequest<MainUnit, Message> action(UnitRequest<AnswerText<Message>, Message> unitRequest) {
final BoxAnswer boxAnswer = answerText.getBoxAnswer().processing(message); final AnswerText<Message> unit = unitRequest.getUnit();
replaceMarkers(answerText, message, boxAnswer); final Message message = unitRequest.getMessage();
final Sending answerTextSending = answerText.getSending(); final BoxAnswer boxAnswer = unit.getBoxAnswer().processing(message);
replaceMarkers(unit, message, boxAnswer);
final Sending answerTextSending = unit.getSending();
if (answerTextSending != null) { if (answerTextSending != null) {
Sender.sends(message, boxAnswer, answerTextSending); Sender.sends(message, boxAnswer, answerTextSending);
} else { } else {
Sender.sends(message, boxAnswer, this.sending); Sender.sends(message, boxAnswer, this.sending);
} }
return answerText; return UnitRequest.of(unit, message);
} }
private void replaceMarkers(AnswerText<Message> answerText, Message message, BoxAnswer boxAnswer) { private void replaceMarkers(AnswerText<Message> answerText, Message message, BoxAnswer boxAnswer) {
@ -46,5 +50,4 @@ public class AnswerTextAction implements ActionUnit<AnswerText<Message>, Message
} }
} }
} }

View File

@ -1,11 +1,12 @@
package dev.struchkov.godfather.core.service.action; package dev.struchkov.godfather.core.service.action;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.exception.TimerSettingException; import dev.struchkov.godfather.context.exception.TimerSettingException;
import dev.struchkov.godfather.core.GeneralAutoResponder; import dev.struchkov.godfather.core.GeneralAutoResponder;
import dev.struchkov.godfather.core.domain.Timer; import dev.struchkov.godfather.core.domain.Timer;
import dev.struchkov.godfather.core.domain.unit.AnswerTimer; import dev.struchkov.godfather.context.domain.unit.AnswerTimer;
import dev.struchkov.godfather.core.domain.unit.MainUnit; import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.core.service.timer.TimerActionTask; import dev.struchkov.godfather.core.service.timer.TimerActionTask;
import dev.struchkov.godfather.core.service.timer.TimerService; import dev.struchkov.godfather.core.service.timer.TimerService;
@ -40,29 +41,32 @@ public class AnswerTimerAction implements ActionUnit<AnswerTimer, Message> {
} }
@Override @Override
public MainUnit action(AnswerTimer answerTimer, Message message) { public UnitRequest<MainUnit, Message> action(UnitRequest<AnswerTimer, Message> unitRequest) {
LocalDateTime timeActive = LocalDateTime final AnswerTimer unit = unitRequest.getUnit();
final Message message = unitRequest.getMessage();
final LocalDateTime timeActive = LocalDateTime
.now(Clock.tickSeconds(ZoneId.systemDefault())) .now(Clock.tickSeconds(ZoneId.systemDefault()))
.plusSeconds(Optional .plusSeconds(Optional
.ofNullable(answerTimer.getTimeDelaySec()) .ofNullable(unit.getTimeDelaySec())
.orElseThrow(() -> new TimerSettingException("Не установлена временная задержка таймера"))); .orElseThrow(() -> new TimerSettingException("Не установлена временная задержка таймера")));
Timer.Builder timer = Timer.builder() final Timer.Builder timer = Timer.builder()
.personId(message.getPersonId()) .personId(message.getPersonId())
.unitAnswer(answerTimer.getUnitAnswer()) .unitAnswer(unit.getUnitAnswer())
.timeActive(timeActive) .timeActive(timeActive)
.periodSec(answerTimer.getTimeDelaySec()) .periodSec(unit.getTimeDelaySec())
.checkLoop(answerTimer.getCheckLoop()); .checkLoop(unit.getCheckLoop());
if (answerTimer.getTimeDeathSec() != null) { if (unit.getTimeDeathSec() != null) {
timer.timeDeath(LocalDateTime timer.timeDeath(LocalDateTime
.now(Clock.tickSeconds(ZoneId.systemDefault())) .now(Clock.tickSeconds(ZoneId.systemDefault()))
.plusSeconds(answerTimer.getTimeDeathSec())); .plusSeconds(unit.getTimeDeathSec()));
} else if (answerTimer.getCheckLoop() == null) { } else if (unit.getCheckLoop() == null) {
timer.timeDeath(timeActive); timer.timeDeath(timeActive);
} }
timerService.add(timer.build()); timerService.add(timer.build());
return answerTimer; return UnitRequest.of(unit, message);
} }
} }

View File

@ -1,10 +1,11 @@
package dev.struchkov.godfather.core.service.action; package dev.struchkov.godfather.core.service.action;
import dev.struchkov.godfather.context.domain.Clarification;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.core.domain.Clarification; import dev.struchkov.godfather.context.domain.unit.AnswerText;
import dev.struchkov.godfather.core.domain.unit.AnswerText; import dev.struchkov.godfather.context.domain.unit.AnswerValidity;
import dev.struchkov.godfather.core.domain.unit.AnswerValidity; import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.core.domain.unit.MainUnit;
import java.util.Set; import java.util.Set;
@ -20,31 +21,37 @@ public class AnswerValidityAction implements ActionUnit<AnswerValidity, Message>
public static final Set<String> WORDS_YES_NO = Set.of("да", "ага", "нет", "неа"); public static final Set<String> WORDS_YES_NO = Set.of("да", "ага", "нет", "неа");
@Override @Override
public MainUnit action(AnswerValidity unit, Message content) { public UnitRequest<MainUnit, Message> action(UnitRequest<AnswerValidity, Message> unitRequest) {
final AnswerValidity unit = unitRequest.getUnit();
final Message content = unitRequest.getMessage();
String message = content.getText(); String message = content.getText();
Long personId = content.getPersonId(); Long personId = content.getPersonId();
if (WORDS_YES.contains(message.toLowerCase())) { if (WORDS_YES.contains(message.toLowerCase())) {
unit.getTempSave().getByKey(personId, "temp").ifPresent(content::setText); unit.getTempSave().getByKey(personId, "temp").ifPresent(content::setText);
return unit.getUnitYes(); return UnitRequest.of(unit.getUnitYes(), content);
} else if (WORDS_NO.contains(message.toLowerCase())) { } else if (WORDS_NO.contains(message.toLowerCase())) {
unit.getTempSave().getByKey(personId, "temp").ifPresent(content::setText); unit.getTempSave().getByKey(personId, "temp").ifPresent(content::setText);
return unit.getUnitNo(); return UnitRequest.of(unit.getUnitNo(), content);
} else { } else {
Clarification clarification = unit.getClarificationQuestion().getClarification(content); Clarification clarification = unit.getClarificationQuestion().getClarification(content);
final String value = clarification.getValue(); final String value = clarification.getValue();
if (value == null) { if (value == null) {
return unit.getUnitNull(); return UnitRequest.of(unit.getUnitNull(), content);
} else { } else {
unit.getTempSave().save(personId, "temp", value); unit.getTempSave().save(personId, "temp", value);
AnswerValidity newValidity = unit.builder() AnswerValidity newValidity = unit.builder()
.clearKeyWords().keyWords(WORDS_YES_NO) .clearKeyWords()
.build(); .stringKeyWords(WORDS_YES_NO)
return AnswerText.builder()
.message(mes -> clarification.getQuestion())
.nextUnit(newValidity)
.build(); .build();
return UnitRequest.of(
AnswerText.builder()
.message(mes -> clarification.getQuestion())
.nextUnit(newValidity)
.build(),
content
);
} }
} }
} }
} }

View File

@ -0,0 +1,38 @@
package dev.struchkov.godfather.core.service.action.cmd;
import dev.struchkov.godfather.context.domain.StorylineHistory;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.cmd.RollBackCmd;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.service.StorylineService;
import dev.struchkov.godfather.core.service.action.ActionUnit;
import java.util.Optional;
public class BackCmdAction<T extends Message> implements ActionUnit<RollBackCmd, T> {
private final StorylineService<T> storyLineService;
public BackCmdAction(StorylineService<T> storyLineService) {
this.storyLineService = storyLineService;
}
@Override
public UnitRequest<MainUnit, T> action(UnitRequest<RollBackCmd, T> unitRequest) {
final RollBackCmd unit = unitRequest.getUnit();
final T message = unitRequest.getMessage();
final int countToBack = unit.getCountBack();
final Optional<StorylineHistory> optHistory = storyLineService.replaceUserToBack(message.getPersonId(), countToBack);
if (optHistory.isPresent()) {
final StorylineHistory history = optHistory.get();
final String unitName = history.getUnitName();
final MainUnit nextUnit = storyLineService.getUnitByName(unitName).orElse(unit);
final T oldMessage = (T) history.getMessage();
return UnitRequest.of(nextUnit, oldMessage);
}
return UnitRequest.of(unit, message);
}
}

View File

@ -0,0 +1,30 @@
package dev.struchkov.godfather.core.service.action.cmd;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.domain.unit.MainUnit;
import dev.struchkov.godfather.context.domain.unit.cmd.TeleportCmd;
import dev.struchkov.godfather.context.service.StorylineService;
import dev.struchkov.godfather.core.service.action.ActionUnit;
import java.util.Optional;
public class TeleportCmdAction<T extends Message> implements ActionUnit<TeleportCmd, T> {
private final StorylineService<T> storyLineService;
public TeleportCmdAction(StorylineService<T> storyLineService) {
this.storyLineService = storyLineService;
}
@Override
public UnitRequest<MainUnit, T> action(UnitRequest<TeleportCmd, T> unitRequest) {
final TeleportCmd unit = unitRequest.getUnit();
final T message = unitRequest.getMessage();
final Optional<MainUnit> optNextUnit = storyLineService.getUnitByName(unit.getUnitNameToTeleport());
return optNextUnit
.map(mainUnit -> UnitRequest.of(mainUnit, message))
.orElseGet(() -> UnitRequest.of(unit, message));
}
}

View File

@ -1,6 +1,7 @@
package dev.struchkov.godfather.core.service.save.data; package dev.struchkov.godfather.core.service.save.data;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.service.save.PreservableData;
import dev.struchkov.haiti.utils.Pair; import dev.struchkov.haiti.utils.Pair;
/** /**

View File

@ -1,6 +1,7 @@
package dev.struchkov.godfather.core.service.save.push; package dev.struchkov.godfather.core.service.save.push;
import dev.struchkov.godfather.context.domain.BoxAnswer; import dev.struchkov.godfather.context.domain.BoxAnswer;
import dev.struchkov.godfather.context.service.save.Pusher;
import dev.struchkov.godfather.context.service.sender.Sending; import dev.struchkov.godfather.context.service.sender.Sending;
import java.util.Map; import java.util.Map;

View File

@ -1,5 +1,6 @@
package dev.struchkov.godfather.core.service.timer; package dev.struchkov.godfather.core.service.timer;
import dev.struchkov.godfather.context.domain.UnitRequest;
import dev.struchkov.godfather.context.domain.content.Message; import dev.struchkov.godfather.context.domain.content.Message;
import dev.struchkov.godfather.context.service.usercode.CheckData; import dev.struchkov.godfather.context.service.usercode.CheckData;
import dev.struchkov.godfather.context.utils.MessageUtils; import dev.struchkov.godfather.context.utils.MessageUtils;
@ -50,17 +51,17 @@ public class TimerActionTask extends TimerTask {
if (!timeDeath(nowDate, timer.getTimeDeath())) { if (!timeDeath(nowDate, timer.getTimeDeath())) {
if (checkLoop != null) { if (checkLoop != null) {
if (checkLoop.checked(emptyMessage)) { if (checkLoop.checked(emptyMessage)) {
generalAutoresponder.answer(emptyMessage, timer.getUnitAnswer()); generalAutoresponder.answer(UnitRequest.of(timer.getUnitAnswer(), emptyMessage));
timerService.remove(timer.getId()); timerService.remove(timer.getId());
} else { } else {
reinstallation(timer); reinstallation(timer);
} }
} else { } else {
generalAutoresponder.answer(emptyMessage, timer.getUnitAnswer()); generalAutoresponder.answer(UnitRequest.of(timer.getUnitAnswer(), emptyMessage));
reinstallation(timer); reinstallation(timer);
} }
} else { } else {
generalAutoresponder.answer(emptyMessage, timer.getUnitAnswer()); generalAutoresponder.answer(UnitRequest.of(timer.getUnitAnswer(), emptyMessage));
death(timer, emptyMessage); death(timer, emptyMessage);
} }
} }
@ -74,7 +75,7 @@ public class TimerActionTask extends TimerTask {
private void death(Timer timer, Message emptyMessage) { private void death(Timer timer, Message emptyMessage) {
if (timer.getUnitDeath() != null) { if (timer.getUnitDeath() != null) {
generalAutoresponder.answer(emptyMessage, timer.getUnitDeath()); generalAutoresponder.answer(UnitRequest.of(timer.getUnitDeath(), emptyMessage));
} }
timerService.remove(timer.getId()); timerService.remove(timer.getId());
} }

View File

@ -9,8 +9,8 @@
//import dev.struchkov.godfather.core.domain.unit.AnswerText; //import dev.struchkov.godfather.core.domain.unit.AnswerText;
//import dev.struchkov.godfather.core.domain.unit.MainUnit; //import dev.struchkov.godfather.core.domain.unit.MainUnit;
//import dev.struchkov.godfather.core.domain.unit.UnitActiveType; //import dev.struchkov.godfather.core.domain.unit.UnitActiveType;
//import dev.struchkov.godfather.core.service.save.Preservable; //import dev.struchkov.godfather.context.service.save.Preservable;
//import dev.struchkov.godfather.core.service.save.push.Pusher; //import dev.struchkov.godfather.context.service.save.Pusher;
// //
//import java.util.List; //import java.util.List;
//import java.util.Optional; //import java.util.Optional;

View File

@ -6,7 +6,7 @@
<groupId>dev.struchkov.godfather</groupId> <groupId>dev.struchkov.godfather</groupId>
<artifactId>godfather-bot</artifactId> <artifactId>godfather-bot</artifactId>
<version>0.0.8</version> <version>0.0.9</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
@ -32,12 +32,12 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<godfather.ver>0.0.8</godfather.ver> <godfather.ver>0.0.9</godfather.ver>
<godfather.context.ver>${godfather.ver}</godfather.context.ver> <godfather.context.ver>${godfather.ver}</godfather.context.ver>
<godfather.core.ver>${godfather.ver}</godfather.core.ver> <godfather.core.ver>${godfather.ver}</godfather.core.ver>
<autoresponder.ver>3.0.0</autoresponder.ver> <autoresponder.ver>3.1.0</autoresponder.ver>
<haiti.utils>1.0.2</haiti.utils> <haiti.utils>1.0.2</haiti.utils>
<javax.persistence.api.ver>2.2</javax.persistence.api.ver> <javax.persistence.api.ver>2.2</javax.persistence.api.ver>